我是React的新手,当我阅读文档时,我发现有两种方法可以实现React组件:基于功能的和基于类的。我知道在React 16.8之前不可能管理功能组件中的状态,但是在那之后有React Hooks。
问题是,React Hook似乎有一个限制,它们只能在功能组件内部使用。以服务器-客户端为例,在接收到401时需要更改isAuthenticated
状态。
//client.js
import { useUserDispatch, signOut } from "auth";
export function request(url, args) {
var dispatch = useUserDispatch();
return fetch(url, args).then(response => {
if (response.status === 401) {
logout(dispatch);
}
}
);
//auth.js
import React from "react";
var UserStateContext = React.createContext();
var UserDispatchContext = React.createContext();
function userReducer(state, action) {
...
}
function UserProvider({ children }) {
var [state, dispatch] = React.useReducer(userReducer, {
isAuthenticated: false,
});
return (
<UserStateContext.Provider value={state}>
<UserDispatchContext.Provider value={dispatch}>
{children}
</UserDispatchContext.Provider>
</UserStateContext.Provider>
);
}
function useUserState() {
return React.useContext(UserStateContext);
}
function useUserDispatch() {
return React.useContext(UserDispatchContext);
}
function signOut(dispatch) {
dispatch({});
}
export { UserProvider, useUserState, useUserDispatch, loginUser, signOut };
上面的客户端代码将产生错误“只能在函数组件的主体内部调用挂钩”。因此,也许我必须将var dispatch = useUserDispatch()
行向上移至调用request
的组件,然后将dispatch
作为道具传递给request
。我觉得这是不对的,不仅request
被迫关心一些毫无意义的dispatch
,而且这个dispatch
也会散布到需要request
的所有组件上。
对于基于类的组件,this.state
也不能解决此问题,但是至少我可以使用mobx。
那么还有其他一些解决此问题的理想方法吗?
挂钩是基于类的组件的替代品,您应在项目中选择一个并坚持使用,请勿混淆。有一些创建钩子的动机,正如在文档hook motivation中更好地指出的那样。
您可以分开创建钩子函数,但是它们应由组件consumed
所用。就像将HOC(高阶组件)与基于类的组件一起使用。const myHook = () => { [foo, setFoo] = useState('john') // use effect for example if you need to run something at state updates useEffect(() => { // do something on foo changes }, [foo]) return [foo, setFoo] // returning state and setState you can use them by your component }
现在您有了一个可重复使用的钩子,可以在组件中使用它了:
const myComponent = (props) => { [foo, setFoo] = myHook() const handleFoo = () => { // some logic setFoo(someValue) } return ( <div> <span>{foo}<span> <button onClick={handleFoo}>click</button> </div> ) }
obs:您现在应该避免将变量声明为
var
,大多数情况下都选择const
,并且如果它是需要更新使用let
的值变量(例如数字)。
是,您必须使用Redux或MobX来解决此问题。您必须在Redux或MobX的全局状态下保持isAuthenticated
状态。然后执行一个可以命名为toggleAuthState
的动作,并将“ pass”传递给子组件,然后从那里切换状态。
创建钩子时,必须参考Rules of Hooks