I'm having trouble accessing my updated global state in react via hooks. I created custom hooks to get away from reducers and anything redux because I'm not a fan of it. Everything is working well but i cannot access my state.
Here is how the global state is set up
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
}
I make sure to wrap the store provider around the App component
ReactDOM.render(
<Router basename="">
<Provider initialValue={initialState} >
<App />
</Provider>
</Router>,
document.getElementById("root")
);
The App component is clean and mainly used for routes
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
When I hit the login page, enter login info, and click submit, the state updates. The only thing is I can't access the updated state inside my component.
Heres the login component
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;
and here's the useAuth hook code
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}
}
when the value of auth.isAutheticated coverts to true in the login component, nothing happens. In the provider the state is updated and even in the useAuth hook I console log the current state and its updated. Yet I can't access it in the login component despite using useEffects? is there something I'm missing.
this code only happens like componentdidmount - once:
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
}, [])
change to
useEffect(() => {
if(auth.isAuthenticated === true)
props.history.push('/dashboard')
})