在这里,我尝试使用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用于其他本地状态管理。因此,您不会将所有数据都放在同一存储中,这最终可能会变得非常混乱。