【问题标题】:Synchronously read from the store?从存储中同步读取?
【发布时间】:2018-08-24 18:23:35
【问题描述】:

所以我将 Apollo 用于我的应用程序状态,到目前为止,我有点吃惊,没有与 mapStateToProps 等价的东西。

据我所知,要在我的商店中全局访问任何数据,一旦我获得数据,我需要一个查询来将数据写入商店,然后在我的另一个组件中进行另一个查询来获取它。

此时,其他组件已经安装和渲染了很多,所以内容只是有点闪烁。

在 Redux 中,我可以将新数据添加到我的 reducer 中的存储区,然后任何与 mapStateToProps 连接的东西都可以访问它。

有没有等价物?还是一切都需要经过异步查询?有没有其他人觉得这是一种巨大的痛苦?

例如,在一个组件中,我得到了一些邀请数据:

   this.props.client.query({
        query: REQUEST_ACTION_DATA,
        variables: {
            id: actionData.id,
            type: actionData.type
        }
    }).then(data => {
        this.props.client.writeQuery({query: GET_ACTION_DATA, data: {
            action: {
                type: data.data.actionData.type,
                object: data.data.actionData.invitation,
                __typename: 'ActionDataPayload'
            }
        }})

        this.props.history.push('/auth/register')
    })

...然后在我的其他组件中我有这个:

componentWillMount() {
    const authToken = localStorage.getItem(AUTH_TOKEN);

    if (authToken) {
        this.props.history.push('/')
    }else{
        this.props.client.query({
            query: GET_ACTION_DATA
        }).then(data => {
            if(data.data && data.data.action && data.data.action.type == 'invite'){
                this.setState({
                    invitation: data.data.action.object
                })
            }
            console.log(data)
        })
    }
}

忽略为如此简单的事情编写所有这些非常笨拙的事实,是否有一种无需等待即可访问存储数据的方法?

【问题讨论】:

  • 好吧,使用 withApollo 高阶组件并不是使用 Apollo 的方式。你想使用 graphql HOC(一个增压的 redux connect)或 Query 组件,除非你正在做一些非常特别的事情(我们有一个大型生产应用程序并且从不使用 withApollo,这是一种反模式)。这是一个关于如何做非常特别的事情的问题,还是我应该尝试解释 Apollo 缓存的工作原理(以及如何从中选择数据)?
  • 嘿@Herku,非常感谢您的回复。我没有做任何特别的事情,真的。只是传递客户端状态。我在几个组件中使用compose 和graphql HOC,但它似乎只是withApollo 的更详细用法。如果您有时间,了解一下两者之间的区别会非常有用!

标签: reactjs graphql react-apollo


【解决方案1】:

来自 react-apollographql 高阶组件是来自 redux 的增压 connect。它将执行以下操作:

当组件挂载时,它将尝试在 Apollo 缓存上执行查询。您可以将查询视为DSL,不仅可以从服务器中选择数据,还可以从商店中选择数据!如果这可行,该组件几乎会立即被来自商店的data 填充,并且不会执行任何远程请求。如果数据在存储中不可用,则会触发接收数据的远程请求。这会将loading 属性设置为true

Apollo 缓存是一个标准化的存储,与您的 redux 存储非常相似。但是由于经过深思熟虑的 GraphQL 限制,标准化可以自动发生,您不必为商店的结构而烦恼。这使程序员可以完全忘记存储、选择器和请求(除非您正在对代码进行大量性能优化)。欢迎来到 GraphQL 前端框架的声明之美!您声明您想要的数据以及它如何到达那里是完全透明的。

export default graphql(gql`{ helloWorld }`)(function HelloWorld({ data }) {
  if (data.loading) {
    return <div>Loading the simple query, please stand by</div>;
  }
  return <div>Result is: {data.helloWorld}</div>;
});
  • 没有选择器,没有发生非规范化。这是由 Apollo Client 完成的!当缓存自动更新时,你会得到更新的数据,类似于 Redux。
  • componentWillMount 检查数据是否已存储并触发请求操作。 Apollo 将进行检查并触发查询。
  • 没有对响应数据进行标准化(也由 Apollo Client 为您完成)

如果您执行上述任何操作,您可能错误地使用了 Apollo Client。当您想优化查询时start here

【讨论】:

  • 这是一个绝妙的答案,Herku。我想很多人都会从中受益。非常感谢!
猜你喜欢
  • 2012-07-28
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多