2

我有一个使用react-router-dom.

// App.js
function App() {
    return (
        <SiteContextProvider>
            <Switch>
                <Route path="/player/:slug"><PlayerPage /></Route>
                <Route default><NotFoundPage /></Route>
            </Switch>
        </SiteContextProvider>
        );
}

PlayerPage 子组件将 SiteContext 设置为slugURL 中传递的参数的值。

// 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设置上下文值的 reloading PlayerPage。这会导致无限循环并且我的代码崩溃。如何让 PlayerPage 只设置一次上下文的值?

4

1 回答 1

3

你的问题在这里:

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>;
}
于 2020-09-16T15:59:54.140 回答