我有这段代码:https://codesandbox.io/s/507w9qxrrl
我不明白:
1)如何在以下情况下重新渲染()Menu
组件:
this.props.client.query({
query: CURRENT_USER_QUERY,
fetchPolicy: "network-only"
});
如果我登录(),我希望我的Menu
组件重新呈现()本身。但没什么。
只有当我点击Home链接时,它才会重新渲染()。我怀疑是因为我用它来渲染它:
<Route component={Menu} />
用于在react-routers道具中拥抱它。这是错的吗?
另外,如果在this.props
之后检查菜单login()
,我会永远看到loading: true
。为什么呢?
2)如果未经过身份验证,如何阻止Menu
组件查询(例如:localStorage中没有令牌);我在Menu
组件中使用此代码:
export default graphql(CURRENT_USER_QUERY)(Menu);
3)这是正确的方法吗?
答案 0 :(得分:3)
首先,让我回答您的第二个问题:您可以使用skip query option跳过操作。
export default graphql(CURRENT_USER_QUERY, {
skip: () => !localStorage.get("auth_token"),
})(Menu);
现在的问题是当本地存储发生变化时如何重新呈现此组件。通常react不会侦听本地存储以触发重新渲染,而是使用以下三种方法之一重新渲染:
(请注意,订阅上下文的更改也会触发重新渲染,但我们不想乱搞上下文; - ))
您可能希望使用2.和3.或1.和2的组合。
在您的情况下,改变路线就足够了(就像在登录功能中一样)。如果这不起作用,您可以在登录后使用this.forceUpdate()
上的回调属性在App组件上调用<Login onLogin={() => this.forceUpdate() } />
。
答案 1 :(得分:2)
<强> EDITED 强>
1)我刚创建了新链接https://codesandbox.io/s/0y3jl8znw
您想要使用componentWillReceiveProps
方法获取用户数据:
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)
})
}
这将使组件重新渲染。
2)现在,当我们在组件的生命周期方法中移动查询调用时,我们可以完全控制它。如果你只想在localstorage中有东西时调用查询,你只需要在简单的条件下包装查询:
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)您希望将全局应用程序状态存储在redux存储中。否则,每次需要使用它时都必须获取用户信息。我建议您在state
组件中定义App
并在那里存储所有全局值。