[英]React Router V6 nested Routes with i18n
我有一个关于嵌套 i18n 的 React Router V6 的问题。
这是我的第一个多语言服务。
const MainPage:React.FC = () => {
const lang = i18n.language;
return (
<>
<Wrapper>
<Routes>
{/* Main */}
<Route path={`/`} element={<Home />}>
<Route path={`${lang}`}>
<Route path={`service`}>
<Route path={'slack'} element={<Slack />} />
</Route>
</Route>
{/* <Route path={`service/dooray`}element={<Dooray />} /> */}
{/* <Route path={`contact`} element={<Contact />} /> */}
{/* <Route path={`app/sign-in`} element={<SignIn />} /> */}
{/* <Route path={`app/sign-up`} element={<SignUp />} /> */}
{/* <Route path={`app/mail-code`} element={<MailCode />} /> */}
{/* <Route path={`app/password/reset`} element={<PwdReset />} /> */}
{/* <Route path={`policies/privac`} element={<Privacy />} /> */}
{/* <Route path={`policies/terms`} element={<Terms />} /> */}
</Route>
{/* <Route path={`*`} element={<>NOT FOUND</>} /> */}
{/* test */}
</Routes>
</Wrapper>
<ParentModal />
</>
如果我输入 localhost:3000/en,则会出现错误'This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.'
我该如何解决它..
我想要 /en => go 到英文页面,/jp => go 到日文页面
const MainPage:React.FC =() => {
...
<Route path={`/`} element={<Home />}>
<Route path={`/${lang}/*`}>
<Route path={`service`}>
<Route path="slack" element={<Slack />} />
</Route>
</Route>
</Route>
}
const Home:React.FC = () => {
return (
<>
... UI, JSX
<Outlet />
</>
)
}
我添加了一个<Outlet />
。 但是如果我输入 '/ko/service/slack',现在渲染<Home />
<Route path={`/`} element={<Home />}>
<Route path="service">
<Route path="slack" element={<Slack />} />
<Route path="dooray" element={<Dooray />} />
</Route>
</Route>
嵌套路由不起作用.. :(
错误'This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.'
表示父路由没有为要渲染的嵌套路由渲染Outlet
组件。 渲染Home
组件的路由似乎没有渲染Outlet
。
更新Home
组件以呈现Outlet
。 请注意,没有element
prop 的Route
组件将默认呈现一个Outlet
。
例子:
import { Outlet } from 'react-router-dom';
const Home = () => {
...
return (
<>
... home page UI/JSX ...
<Outlet />
</>
);
};
...
const MainPage:React.FC = () => {
const lang = i18n.language;
return (
<>
<Wrapper>
<Routes>
{/* Main */}
<Route path="/" element={<Home />}>
<Route path={lang}> // <-- renders Outlet by default
<Route path="service"> // <-- renders Outlet by default
<Route path="slack" element={<Slack />} />
</Route>
</Route>
...
</Route>
...
{/* test */}
</Routes>
</Wrapper>
<ParentModal />
</>
);
};
如果Home
和Slack
组件是分开独立的,那么将Home
组件移动到索引路由中,并简化到Slack
组件的路由。
<Routes>
<Route path="/">
<Route index element={<Home />} />
<Route path={`${lang}/service/slack`} element={<Slack />} />
</Route>
</Routes>
我有完全相同的用例(本地化反应路由器 v6)并想出了以下 LangRouter存储库链接:
const LangRouter = () => {
const { i18n } = useTranslation(),
{ pathname, search, hash } = useLocation(),
navigate = useNavigate(),
availableLocales = ['en', 'ar'],
defaultLocale = (
getDefaultLanguage() === 'en' || getDefaultLanguage() === 'ar' ? getDefaultLanguage() : 'en'
) as string,
pathnameLocale = pathname.substring(1, 3).toLowerCase(),
[locale, setLocale] = useState(defaultLocale),
loaderTimerRef = useRef<any>(),
[isLoading, setIsLoading] = useState(true);
useEffect(() => {
loaderTimerRef.current = setTimeout(() => {
setIsLoading(false);
clearTimeout(loaderTimerRef.current);
}, 300);
}, []);
useEffect(() => {
if (availableLocales.includes(pathnameLocale)) {
updateLocale(pathnameLocale);
} else if (pathname === '/') {
updateLocale(defaultLocale);
}
// eslint-disable-next-line
}, [pathname]);
useEffect(() => {
let lang = defaultLocale;
if (availableLocales.includes(pathnameLocale)) {
lang = pathnameLocale;
setLanguageHandler(lang);
} else if (pathname === '/') {
setLanguageHandler(lang);
}
// eslint-disable-next-line
}, [locale]);
const setLanguageHandler = (lang: string) => {
if (lang === 'en') {
i18n.changeLanguage('en-US');
} else {
i18n.changeLanguage('ar-SA');
}
};
const updateLocale = (newLocale: string) => {
const newPath = `/${newLocale}` + pathname.substring(3);
if (locale !== newLocale) {
if (newPath === `/${newLocale}/` || newPath === `/${newLocale}` || pathname === '/') {
navigate(getHomePageUrl(newLocale));
} else {
navigate(`${newPath}${hash}${search}`);
}
setLocale(newLocale);
} else if (newPath === `/${newLocale}/` || newPath === `/${newLocale}` || pathname === '/') {
if (isAuthenticated()) {
navigate(getHomePageUrl(newLocale));
} else {
navigate(getLoginPageUrl(newLocale));
}
}
};
if (isLoading) {
return (
<div className="loader-wrapper">
<LoadingIcon />
</div>
);
}
return (
<LocaleContext.Provider value={{ locale, setLocale: updateLocale }}>
<Routes>
<Route path={`/${locale}`} element={<App />}>
{publicRoutes.map((el, i) => (
<Route
key={i}
path={el.path(locale)}
element={
<PublicRouteGuard
restricted={el.restricted}
redirect={el.redirect ? el.redirect(locale) : undefined}
>
{el.element}
</PublicRouteGuard>
}
/>
))}
{privateRoutes.map((el, i) => (
<Route
key={i}
path={el.path(locale)}
element={
el.permissions ? (
<RestrictedRouteGuard requiredPermissions={el.permissions}>
{el.element}
</RestrictedRouteGuard>
) : (
<PrivateRouteGuard>{el.element}</PrivateRouteGuard>
)
}
>
{el.children &&
el.children.map((innerEl, innerI) => (
<Route key={innerI} path={innerEl.path(locale)} element={innerEl.element} />
))}
</Route>
))}
</Route>
<Route path="*" element={<NotFoundPage />} />
</Routes>
</LocaleContext.Provider>
);
};
export default LangRouter;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.