Code for request:
export class LogInContainer extends Component {
submit = (values) => {
const { mutate } = this.props;
mutate({
variables: {
email: values.email,
password: values.password,
},
})
.then((res) => {
const token = res.data.login.token;
localStorage.setItem("token", token);
const user = res.data.login.user;
const { logIn } = this.props;
logIn(user);
this.props.history.push("/pages/processes");
})
.catch((error) => {
const errorMessage = error.message;
const { logInError } = this.props;
logInError(errorMessage);
});
};
render() {
const { error, logInCleanError } = this.props;
return (
<LogIn
onSubmit={this.submit}
errorMessage={error}
logInCleanError={logInCleanError}
/>
);
}
}
export default pose(
graphql(LOG_IN),
withRouter,
connect(({ errors }) => ({ error: errors.log_in_error }), {
logInError,
logInCleanError,
logIn,
})
)(LogInContainer);
Code for reducer:
const initialState = {
user: {
id: "",
firstName: "",
secondName: "",
email: "",
isAuth: localStorage.getItem('token') ? true : false,
},
};
export const userReducer = (state = initialState, { type, user }) => {
switch (type) {
case LOG_IN:
return {
...state,
user: {
id: user.id,
firstName: user.firstName,
secondName: user.secondName,
email: user.email,
isAuth: true,
},
};
case CURRENT_USER:
return {
...state,
user: {
id: user.id,
firstName: user.firstName,
secondName: user.secondName,
email: user.email,
isAuth: true,
},
};
case LOG_OUT:
return {
...state,
user: {
id: "",
firstName: "",
secondName: "",
email: "",
isAuth: false,
},
};
default:
return state;
}
};
I save JWT and put it in the headers for every request like:
const client = new ApolloClient({
uri: "http://localhost:4000/api",
request: (operation) => {
const token = localStorage.getItem("token");
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : "",
},
});
},
});
And I protect my routers like:
const App = ({ authorized }) => {
return (
<Switch>
{!authorized ? (
<Route path="/auth">
<Auth />
</Route>
) : (
<Route path="/pages">
<Pages />
</Route>
)}
<Redirect from="/" to="/auth/login" />
</Switch>
);
};
export default App;
After refreshing the page being logged in, I don't lose JWT and stay in the system, but I lose redux state with user's firstname, secondname and etc. which I need to show on the page. So what is the proper way to save redux state in that case without plugins like redux-persist or something else
Code for request:
export class LogInContainer extends Component {
submit = (values) => {
const { mutate } = this.props;
mutate({
variables: {
email: values.email,
password: values.password,
},
})
.then((res) => {
const token = res.data.login.token;
localStorage.setItem("token", token);
const user = res.data.login.user;
const { logIn } = this.props;
logIn(user);
this.props.history.push("/pages/processes");
})
.catch((error) => {
const errorMessage = error.message;
const { logInError } = this.props;
logInError(errorMessage);
});
};
render() {
const { error, logInCleanError } = this.props;
return (
<LogIn
onSubmit={this.submit}
errorMessage={error}
logInCleanError={logInCleanError}
/>
);
}
}
export default pose(
graphql(LOG_IN),
withRouter,
connect(({ errors }) => ({ error: errors.log_in_error }), {
logInError,
logInCleanError,
logIn,
})
)(LogInContainer);
Code for reducer:
const initialState = {
user: {
id: "",
firstName: "",
secondName: "",
email: "",
isAuth: localStorage.getItem('token') ? true : false,
},
};
export const userReducer = (state = initialState, { type, user }) => {
switch (type) {
case LOG_IN:
return {
...state,
user: {
id: user.id,
firstName: user.firstName,
secondName: user.secondName,
email: user.email,
isAuth: true,
},
};
case CURRENT_USER:
return {
...state,
user: {
id: user.id,
firstName: user.firstName,
secondName: user.secondName,
email: user.email,
isAuth: true,
},
};
case LOG_OUT:
return {
...state,
user: {
id: "",
firstName: "",
secondName: "",
email: "",
isAuth: false,
},
};
default:
return state;
}
};
I save JWT and put it in the headers for every request like:
const client = new ApolloClient({
uri: "http://localhost:4000/api",
request: (operation) => {
const token = localStorage.getItem("token");
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : "",
},
});
},
});
And I protect my routers like:
const App = ({ authorized }) => {
return (
<Switch>
{!authorized ? (
<Route path="/auth">
<Auth />
</Route>
) : (
<Route path="/pages">
<Pages />
</Route>
)}
<Redirect from="/" to="/auth/login" />
</Switch>
);
};
export default App;
After refreshing the page being logged in, I don't lose JWT and stay in the system, but I lose redux state with user's firstname, secondname and etc. which I need to show on the page. So what is the proper way to save redux state in that case without plugins like redux-persist or something else
Share Improve this question asked May 20, 2020 at 19:07 rgdzvrgdzv 5056 silver badges20 bronze badges 1-
Look at
redux-persist
– dwjohnston Commented May 24, 2020 at 22:41
4 Answers
Reset to default 2As Dan Abramov suggests you should use the local storage
in the store's subscribe
method:
store.subscribe(() => {
// persist your state
})
Before creating the store, read those persisted parts:
const persistedState = // ...
const store = createStore(reducer, persistedState)
If you use
bineReducers()
you’ll notice that reducers that haven’t received the state will “boot up” as normal using their defaultstate
argument value. This can be pretty handy.It is advisable that you debounce your subscriber so you don’t write to localStorage too fast, or you’ll have performance problems.
Finally, you can create a middleware that encapsulates that as an alternative, but I’d start with a subscriber because it’s a simpler solution and does the job well.