3

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

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.

4

2 回答 2

3

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

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

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

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

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

于 2016-01-07T18:11:58.207 回答
1

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

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

于 2015-12-18T01:50:58.587 回答