You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* // Keep string "fragments" scoped within the use case.
505
+
* // I.e. random translations should not be injected into other translations,
506
+
* // unless it is clear that they belong together and function well.
507
+
* scopedStopCountOnRoute: {
508
+
* stopCount: "1 pysäkki",
509
+
* stopCount__other: "{{count}} pysäkkiä",
510
+
* busRouteStopCount: "Bussireittillä {{routeLabel}} on $t(scopedStopCountOnRoute.stopCount, { \"count\": {{stopCount}} }).",
511
+
* tramRouteStopCount: "Ratikkareitillä {{routeLabel}} on $t(scopedStopCountOnRoute.stopCount, { \"count\": {{stopCount}} }).",
512
+
* },
513
+
* compelexLongText: "Instructional text about color use in <b>Jore</b>. <BusColor>This color is used for busses in Jore<BusColor>, <TramColor>...</TramColor>. See <LinkToDocumentation>Color guide</LinkToDocumentation> for more indetail instructrions."
514
+
*
515
+
*
516
+
* // Bad strings
517
+
* routeCountOne: '1 route'
518
+
* routeCountPlural: '{{count}} routes'
519
+
*
520
+
* // Defined on line 200. Last change: 2024-01-31: Decapitalize route type on RoutePage
521
+
* routeType: {
522
+
* bus: 'bussireitti',
523
+
* tram: 'ratikkareitti'
524
+
* },
525
+
* // ... 2000 other translations here
526
+
* // Defined on line 2500. Last change: 2026-04-02: Make text more fluid on StopPage
527
+
* stopCount: "Pysäkkien lukumäärä: {{count}}",
528
+
* // Defined on line 4000. Last change: 2022-05-05: Add nice Route header line to LinePage
529
+
* stopCountOnRoute: "{{type}}llä {{routeLabel}} on $t(stopCount, { \"count\": {{stopCount}} })."
530
+
*
531
+
* compelexTextFragments: {
532
+
* intro: "Instructional text about color use in",
533
+
* jore: "Jore",
534
+
* bus: "This color is used for busses in Jore",
535
+
* tram: "...",
536
+
* see: "See",
537
+
* link: "Color guide",
538
+
* more: "for more indetail instructrions."
539
+
* }
540
+
* }
541
+
*/
542
+
543
+
// Always stay within React's reactive context.
544
+
// Access i18next trough the:
545
+
const { t, i18n } =useTranslation(); // Hook
546
+
547
+
// Use the new Typed selectorApi to choose strings
548
+
const goodSelection =t(($) =>$.myString);
549
+
const badSelection =t('myString'); // Won't even compile anymore, with selector API activated
550
+
551
+
// If you need to access translations outside of React component or hook, either:
552
+
// Pass troug the t-function instance into the function, from the calling React context.
553
+
function passInT(t:TFunction, value:SomeEnum):ReactNode {
554
+
switch (value) {
555
+
caseSomeEnum.A:
556
+
returnt(($) =>$.someEnumA);
557
+
caseSomeEnum.B:
558
+
returnt(($) =>$.someEnumB);
559
+
}
560
+
}
561
+
const passInTUsed =passInT(t, SomeEnum.A);
562
+
563
+
// Or return a SelectorFunction from the function
564
+
function returnSelector(value:SomeEnum):SelectorParam {
## Loading state of async request handling / indication
479
676
480
677
To have consistency and reduce duplicated code and passing loading states through components we use redux for the loading state of async requests. We have `enum Operation` in `loader.ts` which contains different async operations e.g. `ConfirmTimetablesImport`. When making an async request, you can use the `setLoadingAction` with the correct `Operation` to handle the state. After this you can use the state how you please, but if you want to show the global `LoadingOverlay`, just add the chosen `Operation` to `joreOperations` in `loader.ts`.
0 commit comments