有状态组件在查询重新获取时丢失状态

Stateful components loosing state on query refetch

有状态组件在 Query 组件重新获取时丢失它们的状态是否正确?我是否必须对 Query 个组件内的所有组件使用 Apollo 客户端状态?

这是一个小演示:https://codesandbox.io/s/qxx6jk3yz9(增加计数然后重新获取 - 计数将被重置)

下面是演示代码的主要部分:

<ApolloProvider client={client}>
  <div className="App">
    <Query query={GET_ALL_FILMS}>
      {({ data, loading, refetch }) => {
        if (loading) return "Loading...";

        return <Counter refetch={refetch} />;
      }}
    </Query>
  </div>
</ApolloProvider>

您在 Query 组件的渲染函数中有一个条件,即

if (loading) return "Loading...";

loading 状态不仅在初始加载时更新,而且在任何时候调用重新获取时都会更新。这意味着当您点击重新获取时,只有 Loading... 被渲染并且整个 Counter 组件被卸载。当加载状态变回 false 时,Counter 组件再次呈现,但因为这是一个新组件,所以它以新状态开始。

如果您注释掉条件,您将看到该应用按预期运行。

有多种方法可以解决此问题。这是三个:

  • 通过 Apollo、Redux 或其他一些状态管理库管理状态
  • 提升状态,以便将其存储在 Query 组件的父组件中,然后将状态向下传递给您的 Counter 组件,以及一个对其进行变异的函数。
  • 不是不渲染 Counter 组件,而是将其隐藏,例如将 display 设置为 none