www.carecom.de to uniwersalna (izomorficzna) aplikacja jednostronicowa (SPA) w React z wykorzystaniem Redux, React-Router, TypeScript, Bootstrap oraz backendu ASP.NET Core.
Opiera się na znakomitym projekcie Microsoft ASP.NET Core JavaScript Services. Część rozszerzeń pochodzi od świetnej społeczności na GitHubie, inne zaimplementowałem samodzielnie:
- Obsługa wielu najemców (multi-tenant), bym mógł łatwo wykorzystać całą tę dobroć dla moich klientów
- Lokalizacja (po stronie klienta i serwera)
- Tagi meta i tytuły
- Dodany komponent Google Analytics
- Dodany komponent Google Ads
- Dodany komponent ostrzeżenia o plikach cookie
- Dodany komponent przełącznika cen brutto / netto
- Dodana podstawowa obsługa uwierzytelniania
- Dodany komponent okna modalnego
- Dodany komponent formularza kontaktowego
- Dodany komponent formatowania kodu
- Dodany komponent płynnego przewijania / przewijania do hashtagu
- Sitemap.xml
- Przekazywanie „stanu globalnego" między serwerem a klientem
- Ulepszona obsługa plików cookie
- Zagnieżdżone reduktory redux
- ...
Z czasem będę rozbudowywał ten wpis, opisując więcej aspektów projektu aplikacji. Wyjaśnianie technologii leżących u podstaw wykracza poza zakres tego wpisu.
Na razie jest to bardziej zalążek tego, co nadejdzie.
Uwielbiam:
- jak łatwo Redux pozwala tworzyć komponenty wielokrotnego użytku – albo po prostu komponenty „w locie", jak:
let PhotographySlider = (props) => <Slider id="PhotographySlider" baseUrl="/tenants/carecom/images/photography/slides/" fromNr={1} toNr={42} /> - elegancję ES6, taką jak destrukturyzacja obiektów:
- …
Przyjrzyjmy się fragmentowi głównego komponentu Layout napisanego w React (z użyciem JSX; kod w {} to TypeScript) dla tej strony:
return <div className="layoutContainer">
<DocumentMeta {...getMeta()} />
<NavMenu userId={this.props.userId} isLoggedIn={this.props.isLoggedIn} onLogout={this.props.onLogout} />
{this.props.slider}
<main className='container mainLayoutContainer'>
{
breadCrumb &&
<div className='row hidden-xs hidden-sm'>
<div className='col-md-6 breadCrumb'>{breadCrumb}</div>
</div>
}
{
title &&
<div className='row'>
<header className={`col-md - ${(side ? 0 : 3) + (translations ? 6 : 9)} col-xs - ${ translations ? 9 : 12 } `}>
<h1>{title}</h1>
</header>
{
translations &&
<div className='col-xs-3 translations'>
<span className='glyphicon glyphicon-flag'></span> {translations}
</div>
}
</div>
}
<div className='row'>
<div className={`col- md - ${side ? 9 : 12 }`} role='main'>{ this.props.body }</div>
{
side &&
<aside className='col-md-3'>{ side }</aside>
}
</div>
</main>
<footer>
<BottomMenu />
<Footer />
</footer>
</div>
DocumentMeta (z React Document Meta) zapewnia, że informacje takie jak title, description i tagi meta zostaną powiązane z komponentem korzystającym z tego Layoutu. getMeta() pochodzi z modułu pomocniczego, który pobiera metadane dla bieżącej trasy.
Breadcrumb, tytuł i tłumaczenia (linki do innych wersji językowych danej trasy) będą renderowane tylko wtedy, gdy dostarcza je bieżąca trasa.
export default (
<Route path='/' component={Layout}>
{ /* de */ }
<IndexRoute components={EnhHomeComp} />
<Route path="de">
<IndexRoute components={EnhHomeComp} />
<Route path='consulting'>
<IndexRoute components={{ body: Consulting, side: ConsultingQuotation }} />
<Route path='informatiker' components={{ body: ComputerScientist, side: SideHaraldMuehlhoff }} />
<Route path='referenzen' components={{ body: ConsultingReferences }} />
<Route path='remote-support' components={{ body: RemoteSupport, side: SideHaraldMuehlhoff }} />
</Route>
<Route path='distribution'>
<IndexRoute components={{ body: Distribution, side: DistributionQuotation }} />
<Route path='referenzen' components={{ body: DistributionReferences }} />
<Route path='selbstbedienung' components={{ body: SelfService }} />
</Route>
Np. nie każda Route ma komponent side. Ma to wpływ na zastosowane style Bootstrap (className={`col-md-${side ? 9 : 12}`}).
