为什么状态更新了,但我无法通过 React 中的钩子访问它?
Why does the state update but I can't access it via hooks in React?
我在通过挂钩访问 React 中更新的全局状态时遇到问题。我创建了自定义钩子来远离 reducers 和任何 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,我还是无法在登录组件中访问它?有什么我想念的吗?
此代码只发生像 componentdidmount - 一次:
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
}, [])
改为
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
})
我在通过挂钩访问 React 中更新的全局状态时遇到问题。我创建了自定义钩子来远离 reducers 和任何 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,我还是无法在登录组件中访问它?有什么我想念的吗?
此代码只发生像 componentdidmount - 一次:
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
}, [])
改为
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
})