Reputation: 657
I am trying to save a userToken
inside a Redux store and retrieve it. In my index.js
I wrap my App
with Provider
, which takes store
as prop:
import { createStore } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./reducers/rootReducer";
const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
My rootReducer
looks like this:
//Helper functions
import { validateLoginAttempt } from "../helpers/validateLoginAttempt";
const rootReducer = (state, action) => {
switch (action.type) {
case "login":
const isLoggedIn = validateLoginAttempt(action.payload);
default:
console.log("default");
break;
}
};
export default rootReducer;
I have defined a helper function validateLoginAttempt
:
export const validateLoginAttempt = payload => {
if (typeof payload.data.token !== "undefined") {
//Saves in localstorage correctly.
localStorage.setItem("userToken", payload.data.token);
return true;
}
return false;
};
In one of my functional components, I have a fetch()
procedure, which by the end of request to an API, dispatch()
'es action I defined in my rootReducer
:
const dispatch = useDispatch();
<...>
.then(data => {
dispatch({ type: "login", payload: { data } });
history.push("/");
})
Flow of this useCase
works as intended, at least from what I understand, the value gets stored in localStorage
(which I assume is not a Redux store
?). In another of my components I am trying to retrieve userToken
like this:
const userToken = useSelector(state => state.userToken);
This gives me an error
:
Error: An error occured while selecting the store state: Cannot read property 'userToken' of undefined.
If I try to getStore
as follows in my App
component, I get store undefined
:
const store = useStore();
console.log("store", store.getState());
Could someone put me on a right track, cannot figure this out.
Upvotes: 1
Views: 928
Reputation: 22304
There are multiple problems, but the biggest one is related to the basics of reducers:
The reducer is a pure function that takes the previous state and an action, and returns the next state.
You don't return anything from the reducer (implicitly return undefined
), thus causing the TypeError Cannot read property 'userToken' of undefined.
:
const initialState = {};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case "login": {
return {...state, userToken: action.payload.data.token};
}
default:
return state;
}
};
And "a pure function" means no side effects, so the localStorage.setItem
inside validateLoginAttempt
has no place in a reducer and should be placed inside the action creator:
const dispatch = useDispatch();
...
.then(data => {
const isLoggedIn = validateLoginAttempt(data);
if (isLoggedIn) {
dispatch({ type: "login", payload: { data } });
history.push("/");
} else {
console.error("not logged in")
}
})
Upvotes: 1