I'm using React and Redux and storing data in a loggedUser variable upon user login.
my login reducer looks like this:
const loginReducer = (state = null, action) => {
switch (action.type) {
case "SET_USER":
if (action.data) userService.setToken(action.data.token);
return action.data;
default:
return state;
}
};
export const fetchUser = () => {
return dispatch => {
const userStr = window.localStorage.getItem("loggedVintageUser");
const user = JSON.parse(userStr);
if (user) {
dispatch({ type: "SET_USER", data: user });
}
};
};
export const setUser = data => {
return dispatch => {
dispatch({ type: "SET_USER", data });
};
};
export const login = data => {
return async dispatch => {
const user = await loginService.login({
username: data.username,
password: data.password
});
window.localStorage.setItem("loggedVintageUser", JSON.stringify(user));
dispatch({ type: "SET_USER", data: user });
};
};
In my core App component i'm dispatching the fetchUser and setUser creators
useEffect(() => {
fetchUser();
}, [props.fetchUser]);
useEffect(() => {
const loggedUserJSON = window.localStorage.getItem("loggedVintageUser");
if (loggedUserJSON) {
const user = JSON.parse(loggedUserJSON);
props.setUser(user);
userService.setToken(user.token);
}
}, []);
I'm displaying a list of favorite items for a user and when i go to refresh the page, i'm getting the following error:
TypeError: Cannot read property 'favorites' of null
Here is relevant code for my Favorites component. The error is triggered on the loggedUser.favorites data. I can see when visiting the favorites page, the loggedUser field is there and data displays fine but on refresh the loggedUser variable turns to null.
const searchCards = ({ loggedUser, search }) => {
const favorites = loggedUser.favorites;
console.log("FAVORITES", favorites);
return search
? favorites.filter(a =>
a.title
.toString()
.toLowerCase()
.includes(search.toLowerCase())
)
: favorites;
};
const Cards = props => {
useEffect(() => {
setData(props.cardsToShow);
}, [props]);
const [filteredData, setData] = useState(props.cardsToShow);
const mapStateToProps = state => {
return {
baseball: state.baseball,
loggedUser: state.loggedUser,
page: state.page,
entries: state.entries,
query: state.query,
pageOutput: state.pageOutput,
search: state.search,
cardsToShow: searchCards(state)
};
};
const mapDispatchToProps = {
searchChange,
fetchData,
updateUser
};
I tried to add this before i render the data, but it's not working
if (!props.loggedUser) return null;
How can i retain that state if a user is refreshing the page. The odd part is that on my home page where i have a similar sort of display a refresh isn't causing the same problems.