假设我有一个 React 组件,它控制一个包含博客文章内容的 textarea。当用户更改博客文章时,我使用 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 的情况下实际上并不能很好地工作。

最佳答案

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

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

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

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

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

关于relayjs - 如何避免在 Relay Mutations 中往返传输大量数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34346098/

10-12 15:27