【问题标题】:How do I define a dependency based on a value from a context?如何根据上下文中的值定义依赖项?
【发布时间】:2022-08-13 23:22:16
【问题描述】:

我正在为我的功能性 React 应用程序构建一个身份验证上下文。此上下文将包含当前登录用户的配置文件。

在导航期间,用户可能会注销,在这种情况下,上下文中的配置文件将设置为空。在此之后,我需要将用户重定向到登录页面。

当用户单击注销按钮时,我可以简单地使用重定向来实现这一点,但为了提高我的 React 知识,我尝试使用钩子机制以更好的方式实现这一点。

在全局组件中,例如App,我会尝试将配置文件设置为挂钩的依赖项,并在挂钩中进行重定向,如下所示:

useEffect(() => {
  // redirect...
}, [context.profile])

但是,这不起作用。 context.profile 不会像它是组件的状态变量那样被监视。

我尝试了一个混合解决方案:我会将配置文件值存储在组件的状态变量中,并在更新时更新状态和上下文,使用减速器而不是状态:

  const [profile, setProfile] = useReducer((value, value2) => {
    context.profile = value2
    return value2
  }, 0)

这确实有效,因为它使我能够调用 useEffect 回调以进行重定向,并使用上下文读取任何组件中的配置文件。

这是一个有效的解决方案,但对我来说仍然有点老套,特别是因为它暗示了双重事实来源。

您可以在此处找到复制示例:https://jsfiddle.net/hrje2t86/15/

我想知道是否有更好的方法来观察外部值?

    标签: reactjs react-hooks


    【解决方案1】:

    解决方案是将组件包装在提供程序组件中。 提供者组件将具有配置文件状态,这将是事实的来源。

    为了更新配置文件,我们会要求提供者组件使用setProfile 更新配置文件。回调将更新提供程序中的配置文件和所有子组件。因此,后者可以使用提供者组件配置文件作为依赖项。

    上下文,在 AuthContext.js 中定义:

    import React from "react"
    
    const AuthContext = React.createContext({})
    
    export default AuthContext
    

    为 AuthContext 提供上下文的提供程序组件将是 AuthProvider.js :

    function AuthProvider(props) {
        const [profile, setProfile] = useState({})
    
        const providerData = {
            profile,
            setProfile,
        }
    
        return (
            <AuthContext.Provider value={providerData}>
                {props.children}
            </AuthContext.Provider>
        )
    }
    

    只需为您的组件提供 Provider 组件:

    <AuthProvider>
        <MyComponent />
    </AuthProvider>
    

    并在您的组件中使用您的上下文。不要忘记将authContext.profile 定义为需要的依赖项。在以下示例中,每当配置文件更改时都会调用效果。

    function MyComponent() {
        const authContext = useContext(AuthContext)
    
        useEffect(() => {}, [authContext.profile])
    
        return (<div></div>)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-18
      • 2013-11-20
      • 2021-06-02
      • 2020-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多