【问题标题】:How do I avoid round-tripping large quantities of data in Relay Mutations?如何避免在 Relay Mutations 中往返大量数据?
【发布时间】:2016-03-24 14:25:08
【问题描述】:

假设我有一个控制 textarea 的 React 组件,该 textarea 包含博客文章的内容。当用户更改博客文章时,我使用 Mutation 更新 Relay Store:

Relay.createContainer(
  React.createClass({
    handleChange(event) {
      Relay.Store.update(new BlogBodyMutation({
        body: event.target.value,
        blog: this.props.blog
      }))
    },
    render() {
      return (
        <textarea
          value={ this.props.blog.body }
          onChange={ this.handleChange }
        />
      );
    }
  }), {
    fragments: {
      blog: () => Relay.QL`
        fragment on Blog {
          body
          ${ BlogBodyMutation.getFragment('blog') }
        }
      `
    }
  }
)

class BlogBodyMutation extends Relay.Mutation {
  static fragments = {
    blog: () => Relay.QL`fragment on Blog { id }`
  };
  getMutation() {
    return Relay.QL`mutation { blog }`
  }
  getVariables() {
    return {
      id: this.props.blog.id,
      body: this.props.body
    }
  }
  getFatQuery() {
    return Relay.QL`fragment on BlogMutationPayload { blog { body } }`
  }
  getConfigs() {
    return [{ type: 'FIELDS_CHANGE', fieldIDs: { blog: this.props.blog.id }}]
  }
}

问题:每次我使用 Mutation 更新 Store 时,Relay 都会将整个博客文章往返于后端!假设帖子是 50KB,即使每次去抖动编辑的去抖动为 50KB + 一些字节。有什么办法可以避免吗?

我已经尝试了一些,但还没有找到可行的解决方案。我尝试使用带有空有效负载且没有字段配置的乐观响应,但这看起来很奇怪,并且在受控的textarea 下实际上效果不佳。

【问题讨论】:

    标签: relayjs


    【解决方案1】:

    检查applyUpdate 方法而不是标准updatehttps://github.com/facebook/relay/blob/master/docs/APIReference-Store.md#applyupdate-static-method

    此函数创建一个事务而不将其提交到您的后端。您可以使用它来消除您的 handleChange 方法。但是,您必须跟踪您的旧突变并在需要时提交它们。

    【讨论】:

    • 感谢 XuoriG。我已经玩过applyUpdate,实际上是为了去抖动。真的很好的补充。尽管如此,对于您最终决定提交的事务,该数据将需要进行往返。正确的?有没有办法使用这个新的 API 来发送数据,而不是期望数据回到响应正文中?我正在考虑类似于中继前世界中的一些事情,您可以在其中输入一些数据并获得 200。
    • 我明白你现在的意思了。据我所知,这是不可能的,虽然也许有人知道一个窍门:)
    • 嘿,刚刚注意到您为applyUpdate() 做了公关。谢谢:D
    【解决方案2】:

    您基本上是在寻求一种永久“写入”商店的乐观更新的方法 - Relay 不支持这种方法。真正影响 Relay 存储的唯一方法是使用实​​际的 GraphQL 突变和查询。

    不过,这并不是世界末日。在您的情况下,您基本上只是希望客户端进行自己的更改,而与服务器的操作无关。

    我建议您在 Relay 之外管理“博客正文”状态。你可以将它存储在任何你喜欢的地方 - 组件状态、Redux 存储等。你可以通过 Relay 查询初始化博客正文状态(这没有什么不同),但之后只需自己管理它。

    要在服务器上记录博客正文更改,请切换回使用 Relay 突变,但不要声明任何 FIELDS_CHANGE 配置或任何东西。这将指示 Relay 不要尝试重新获取博客正文数据并为您节省您试图避免的往返。

    但请记住,使用此解决方案,您需要在正确性(Relay 尝试确保这一点)和性能之间进行直接权衡。当然,这是一个经典的权衡。

    【讨论】:

      猜你喜欢
      • 2013-08-07
      • 2010-10-22
      • 2016-12-19
      • 2012-07-20
      • 2011-04-07
      • 2015-11-11
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多