我在通过钩子进行响应时无法访问更新的全局状态。我创建了自定义的钩子,以避开减速器和任何redux,因为我不喜欢它。一切正常,但我无法进入状态。
这是设置全局状态的方式
import React, {useState, useMemo, useContext} from 'react'
function makeStore() {
// Make a context for the store
const Context = React.createContext();
// Make a provider that takes an initialValue
const Provider = ({ initialValue, children }) => {
// Make a new state instance (could even use immer here!)
const [state, setState] = useState(initialValue);
// Memoize the context value to update when the state does
const contextValue = useMemo(() => [state, setState], [state]);
// Provide the store to children
return <Context.Provider value={contextValue}>{children}</Context.Provider>;
};
// A hook to help consume the store
const useStore = () => useContext(Context);
return { Provider, useStore };
}
const {Provider, useStore} = makeStore();
export {
Provider,
useStore
}
我确保将商店提供商包装在App组件周围
ReactDOM.render(
<Router basename="">
<Provider initialValue={initialState} >
<App />
</Provider>
</Router>,
document.getElementById("root")
);
App组件很干净,主要用于路线
const App = () =>
<div className="App">
<Route exact path="/" component={props => <Landing {...props} />} />
<Route exact path="/login" component={props => <Login {...props} />} />
<Route exact path="/register/:id" component={props => <Register {...props} />}/>
<PrivateRoute path='/:id' Component={<Content />} />
</div>
export default App
当我点击登录页面时,输入登录信息,然后单击提交,状态将更新。唯一的事情是我无法访问组件内部的更新状态。
在这里登录组件
const Login = ({...props}) => {
const { register, handleSubmit } = useForm()
const {auth, setAuth} = useAuth()
const {loginUser} = AuthApi()
const onSubmit = data => (async () => {
const response = await loginUser(data)
setAuth(response, true)
})()
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
}, [])
return(
<div className="Auth" style={{backgroundImage: 'url(' + background + ')'}}>
<div className="Login">
<div className="Auth-Form Login-Form">
<div className="Form-Header">
<h4>
<b>Login</b>
</h4>
</div>
<div className="Form">
<form onSubmit={handleSubmit(onSubmit)}>
<input
placeholder="Email"
name="email"
ref={register({
required: "email required"
})}
/>
<br/>
<input
placeholder="Password"
name="password"
ref={
register({
required: "password required"
})
}
/>
<br />
<input id="submit" type="submit" placeholder="Create Profile"/>
</form>
<p className="">
Don't have an account? <Link to="/register/user">Register</Link>
</p>
<Link to="/" className="">Back to home</Link>
</div>
</div>
</div>
</div>
)
}
export default Login;
这是useAuth挂钩代码
const useAuth = () => {
const [{...auth}, setState] = useStore()
const setAuth = (data, authenticationStatus) => {
setState(state => {
state.auth.token = data.token
state.auth.user = data.user
state.auth.loading = true
state.auth.isAuthenticated = authenticationStatus
})
}
return {auth, setAuth}
}
在登录组件中将auth.isAutheticated值掩盖为true时,什么也没有发生。在提供程序中,状态会更新,甚至在useAuth挂钩中,我也会在控制台中记录当前状态及其更新。即使使用useEffects,我也无法在登录组件中访问它?有什么我想念的吗?
答案 0 :(得分:0)
此代码仅与componentdidmount一样发生-一次:
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
}, [])
更改为
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
})