我正在我的反應路由器中建立兩條路徑來切換我的站點中的語言。與這些路徑關聯的組件只需要執行一個 useEffect 來設定語言(雖然是 i18n),然后重定向到/. 它們看起來像這樣:
const SetEs = () => {
const { i18n } = useTranslation();
useEffect(() => {
localStorage.setItem('preferredLanguage', 'es');
i18n.changeLanguage('es');
}, [])
return (
<Redirect to='/'/>
)
}
const SetCat = () => {
const { i18n } = useTranslation();
useEffect(() => {
localStorage.setItem('preferredLanguage', 'cat');
i18n.changeLanguage('cat');
}, [])
return (
<Redirect to='/'/>
)
}
然后在路由切換...
<Switch>
<Route exact path="/es" >
<SetEs/>
</Route>
<Route exact path="/cat" >
<SetCat/>
</Route>
...
</Switch>
到目前為止,一切都很好。
現在,回顧組件的代碼,我清楚地看到,對我所有未來的“我”和未來的同事來說,抽象一點代碼冗余是非常友好的。所以我將它包裝在一個以 lang 作為引數的函式中......希望從長遠來看它會簡化事情:
const SetLang = (lang: string) => () => {
const { i18n } = useTranslation();
useEffect(() => {
localStorage.setItem('preferredLanguage', lang);
i18n.changeLanguage(lang);
}, [])
return (
<Redirect to='/'/>
)
}
const SetEs = SetLang('es');
const SetCat = SetLang('cat');
但現在我無法通過這個錯誤:React Hook "useTranslation" cannot be called inside a callback
(I think) I know the rules of hooks. I know they shouldn't be called inside nested functions but I thought, up until now, that this referred only to functions nested within a component. Then there is the Don’t call Hooks from regular JavaScript functions but again, this is a regular function which returns a component which in turn calls the hook.
What am I missing? How do I get to be a good colleague nicely abstracting things out in a situation like this? What's the correct way of factoring components?
Thanks!
uj5u.com熱心網友回復:
創建一個自定義掛鉤 -useLang接受lang作為引數:
const useLang = (lang: string) => {
const { i18n } = useTranslation()
useEffect(() => {
localStorage.setItem('preferredLanguage', lang)
i18n.changeLanguage(lang);
}, [lang])
}
創建一個SetLang接受lang作為道具的組件,并呼叫useLang:
interface Props {
lang: string;
}
const SetLang = ({ lang }: Props) => {
useLang(lang)
return (
<Redirect to='/'/>
)
}
在Route傳遞lang道具時使用它:
<Switch>
<Route exact path="/es" >
<SetLang lang="es" />
</Route>
<Route exact path="/cat" >
<SetLang lang="cat" />
</Route>
...
</Switch>
您還可以創建包裝器組件:
const SetEs = () => <SetLang lang="es" />;
const SetCat = () => <SetLang lang="cat" />;
并按照您最初的意圖使用它們:
<Switch>
<Route exact path="/es" >
<SetEs />
</Route>
<Route exact path="/cat" >
<SetCat />
</Route>
...
</Switch>
uj5u.com熱心網友回復:
也許你可以制作一個常規的 React 組件并將 lang 作為 props 傳遞?
const SetLang = ({ lang }) => {
const { i18n } = useTranslation();
useEffect(() => {
localStorage.setItem('preferredLanguage', lang);
i18n.changeLanguage(lang);
}, [])
return (
<Redirect to='/'/>
)
}
<Switch>
<Route exact path="/es" >
<SetLang lang="es"/>
</Route>
<Route exact path="/cat" >
<SetLang lang="cat"/>
</Route>
...
</Switch>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442541.html
標籤:reactjs typescript react-hooks
