问题描述
// App.js
function App() {
return (
<SiteContextProvider>
<Switch>
<Route path="/player/:slug"><PlayerPage /></Route>
<Route default><NotFoundPage /></Route>
</Switch>
</SiteContextProvider>
);
}
PlayerPage子组件将SiteContext设置为URL中传递的参数slug
的值。
// SiteContextProvider.js
export const SiteContext = React.createContext(null);
export function SiteContextProvider(props) {
const [value,setValue] = useState(null);
return <SiteContext.Provider value={{value,setValue}}>{props.children}</SiteContext.Provider>;
}
export function PlayerPage(props) {
const { slug } = useParams();
const { value,setValue } = useContext(SiteContext);
setValue(slug);
return <span>{value}</span>;
}
问题在于,在加载PlayerPage
时,它将调用setValue
,它设置上下文的值,并重新加载PlayerPage
。这导致无限循环,我的代码崩溃。如何使PlayerPage仅设置一次上下文的值?
解决方法
您的问题在这里:
export function PlayerPage(props) {
const { slug } = useParams();
const { value,setValue } = useContext(SiteContext);
// Don't call setValue directly inside the function
setValue(slug);
return <span>{value}</span>;
}
这将更改上下文状态->重新渲染此组件,这将再次更改状态->重新渲染此组件,等等。
相反,您应该在效果内调用它:
export function PlayerPage(props) {
const { slug } = useParams();
const { value,setValue } = useContext(SiteContext);
React.useEffect(() => {
setValue(slug);
},[slug,setValue]);
return <span>{value}</span>;
}