I have this code: https://codesandbox.io/s/507w9qxrrl
I don't understand:
1) How to re-render() Menu
component after:
this.props.client.query({
query: CURRENT_USER_QUERY,
fetchPolicy: "network-only"
});
If I login() I expect my Menu
component to re-render() itself. But nothing. Only if I click on the Home link it re-render() itself. I suspect because I'm using this to render it:
<Route component={Menu} />
for embrace it in react-router props. Is it wrong?
Plus, if inspect this.props
of Menu after login()
I see loading: true
forever. Why?
2) How to prevent Menu
component to query if not authenticated (eg: there isn't a token in localStorage); I'm using in Menu
component this code:
export default graphql(CURRENT_USER_QUERY)(Menu);
3) Is this the right way to go?
First, let me answer your second question: You can skip an operation using the skip query option .
export default graphql(CURRENT_USER_QUERY, {
skip: () => !localStorage.get("auth_token"),
})(Menu);
The problem now is how to re-render this component when the local storage changes. Usually react does not listen on the local storage to trigger a re-render, instead a re-render is done using one of this three methods:
(Note that also a change of a subscribed context will trigger a re-render but we don't want to mess around with context ;-))
You might want to go with a combination of 2. and 3. or 1. and 2. In your case it can be enough to change the route (as you do in the login function). If this does not work you can call this.forceUpdate()
on the App component after Login using a callback property on <Login onLogin={() => this.forceUpdate() } />
.
EDITED
1) I just created new link https://codesandbox.io/s/0y3jl8znw
You want to fetch the user data in the componentWillReceiveProps
method:
componentWillReceiveProps() {
this.props.client.query({query: CURRENT_USER_QUERY})
.then((response) => {
this.setState({ currentUser: response.data.currentUser})
})
.catch((e) => {
console.log('there was an error ', e)
})
}
This will make the component re-render.
2) Now when we moved the query call in the component's lifecycle method we have full control over it. If you want to call the query only if you have something in localstorage you just need to wrap the query in a simple condition:
componentWillReceiveProps() {
if(localstora.getItem('auth_token')) {
this.props.client.query({query: CURRENT_USER_QUERY})
.then((response) => {
this.setState({ currentUser: response.data.currentUser})
})
.catch((e) => {
console.log('there was an error ', e)
})
}
}
3) You want to store the global application state in redux store. Otherwise you will have to fetch the user info every time you need to work with it. I would recommend to define a state
in you App
component and store all the global values there.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.