React,Apollo 2,GraphQL,身份验证。如何在登录后重新渲染组件

时间:2017-12-05 13:58:52

标签: javascript reactjs graphql apollo react-apollo

我有这段代码: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)这是正确的方法吗?

2 个答案:

答案 0 :(得分:3)

首先,让我回答您的第二个问题:您可以使用skip query option跳过操作。

export default graphql(CURRENT_USER_QUERY, {
  skip: () => !localStorage.get("auth_token"),
})(Menu);

现在的问题是当本地存储发生变化时如何重新呈现此组件。通常react不会侦听本地存储以触发重新渲染,而是使用以下三种方法之一重新渲染:

  1. 组件的状态更改
  2. 组件的父级重新呈现(通常使用子项的新道具)
  3. 在组件上调用
  4. forceUpdate

    (请注意,订阅上下文的更改也会触发重新渲染,但我们不想乱搞上下文; - ))

    您可能希望使用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并在那里存储所有全局值。