从孩子设置上下文会导致无限调用循环

Posted

技术标签:

【中文标题】从孩子设置上下文会导致无限调用循环【英文标题】:Setting context from child causes infinite call loop 【发布时间】:2021-01-03 12:05:58 【问题描述】:

我有一个使用 react-router-dom 的应用程序。

// 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 只设置一次上下文的值?

【问题讨论】:

【参考方案1】:

你的问题在这里:

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>;

【讨论】:

以上是关于从孩子设置上下文会导致无限调用循环的主要内容,如果未能解决你的问题,请参考以下文章

盖茨比:上下文更新导致无限渲染循环

React:在 useEffect 中调用上下文函数时防止无限循环

Angular 7:从订阅内部调用 ChangeDetectorRef detectChanges() 会导致无限循环

PHP二叉树递归遍历无限循环问题

向上滚动时动态设置 UITextView 排除路径会导致无限循环

React:如何使用相同类型的多个上下文,同时允许孩子从所有上下文中读取数据