WEB程序员笔记

一个前端开发工程师的个人博客

React上下文挂钩vs Redux挂钩

在这里,我尝试使用Redux和Context Provider实现相同的登录例程。两者都以完全相同的方式并使用相似的语法来完成。

提供者

首先,您需要提供对状态的访问。Redux和Context使用名为的组件进行此操作Provider

Redux Provider接受store具有状态的prop ,并具有如何更新它的规则。

const store = createStore(/* rules to set store */)

<Provider store={store}>
   <App />
</Provider>

上下文Provider接受可以向下传递给的值Consumer。但是您也可以随意重写它Provider以对其进行自定义(这实际上是我们想要的)。

<Provider value={/* some value, optional */}>
   <App />
</Provider>

消费者

得到

Redux提供了useSelector挂钩,可以从您感兴趣的状态中获取价值。

  const { isLoggedIn } = useSelector(state => ({
    isLoggedIn: state.isLoggedIn
  }));

上下文useContext为此提供了挂钩。


// import context as AuthContext

const { isLoggedIn } = useContext(AuthContext);

您还可以更新状态。

Redux为您提供了一种触发商店更新的调度方法。Ofc,您需要自己在reducer中编写这些规则。

const dispatch = useDispatch();
dispatch({
  type: SET_LOGIN_STATUS,
  isLoggedIn: true
});

使用React Context,您需要在内部实现update方法Provider,然后通过相同的useContext钩子使用它。

// import context as AuthContext

const { login } = useContext(AuthContext);
login();

商业逻辑

上下文提供者

这是Provider具有状态和更新状态的函数的上下文实现。最后,您需要在value属性中进一步传递它,以使其可用于Consumer。对我来说看起来很简单。
检查Codesandbox上Context的完整代码

export const AuthContext = React.createContext(null);

const initialState = {
  isLoggedIn: false,
  isLoginPending: false,
  loginError: null
}

export const ContextProvider = props => {
  const [state, setState] = useState(initialState);

  const setLoginPending = (isLoginPending) => setState({
    ...state,
    isLoginPending
  });
  const setLoginSuccess = (isLoggedIn) => setState({
    ...state,
    isLoggedIn
  });
  const setLoginError = (loginError) => setState({
    ...state,
    loginError
  });

  const login = (email, password) => {
    setLoginPending(true);
    setLoginSuccess(false);
    setLoginError(null);

    fetchLogin( email, password, error => {
      setLoginPending(false);

      if (!error) {
        setLoginSuccess(true);
      } else {
        setLoginError(error);
      }
    })
  }

  return (
    <AuthContext.Provider
      value={{
        state,
        login,
        logout,
      }}
    >
      {props.children}
    </AuthContext.Provider>
  );

Redux商店

使用Redux,您需要编写更多的代码行。并添加thunk中间件(如果要使其异步运行),而且大多数情况下可能是这样。有关如何执行此操作的文章很多,因此我将跳过完整的代码库,您可以在Codesandbox上检查Redux的完整代码

其他

因此,看起来Context和Redux挂钩可以互换使用,也可以轻松地一起使用。例如,Redux用于主存储,而Context用于其他本地状态管理。因此,您不会将所有数据都放在同一存储中,这最终可能会变得非常混乱。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注