2

使用 Relay Modern v.1.4.1,考虑以下List组件。

它需要两个 props foo,并使用这些 props 和 GraphQL 查询的结果bar渲染一个组件:Table

class List extends React.Component {

  constructor(props) {
    super(props);
    // I accept this.props.foo and this.props.bar
    this.renderQuery = this.renderQuery.bind(this);
  }

  render() {
    return <QueryRenderer
      environment={this.props.relayEnvironment}
      query={SomeQuery}
      variables={{
        count: 20,
      }}
      render={this.renderQuery}
    />;
  }

  renderQuery(readyState) {
    console.log("List component props:");
    console.log(this.props);
    return <Table 
      foo={this.props.foo} bar={this.props.bar} 
      data={readyState.data}
    />
  }

}

现在,对于Table组件的初始渲染foobar正确设置,但是如果foobar之后发生更改,新值不会传播到Table组件,因为QueryRenderer.

由于只有在for更改时不会触发该方法的QueryRenderer唯一重新渲染,因为没有看到需要它,因此组件保留旧的 prop 值。variablesSomeQueryrenderQueryQueryRendererTable

由于将 props 传递给孩子是一项非常常见的任务,因此忽略父母 props 更改的事实QueryRenderer造成了很大的问题。我一直想知道解决方案可能是什么,并提出了一些选择:

  1. 使用Context绕过此行为。然而,除非你有充分的理由,否则通常不鼓励使用 Context + 感觉就像是一种肮脏的黑客来规避这个问题。
  2. 强制QueryRenderer重新渲染与readyState以前相同。这也许可以实现,refs但您需要自己检查何时重新渲染。
  3. 不知何故QueryRenderer关心我的道具。QueryRenderer这显然是正确的方法,但我在文档中没有找到任何允许这样做的东西,所以我需要做一些事情,比如从实现这种行为的它的或其子类创建一个高阶组件。

理想情况下,我希望有一种本地方式来QueryRenderer查看道具更改,例如

<QueryRenderer
  environment={this.props.relayEnvironment}
  query={SomeQuery}
  variables={{
    count: 20,
  }}
  render={this.renderQuery}
  propagateProps={this.props}
/>

或者

<QueryRenderer
  environment={this.props.relayEnvironment}
  query={SomeQuery}
  variables={{
    count: 20,
  }}
  render={this.renderQuery}
  {...this.props}
/>

有任何想法吗?

4

1 回答 1

0

删除您的 Class 组件并将上面的代码更改为:

const List = (parentProps) => (
  <QueryRenderer
    environment={parentProps.relayEnvironment}
    query={SomeQuery}
    variables={{
      count: 20,
    }}
    render={({ props }) => (
      <Table 
        foo={this.parentProps.foo} bar={this.parentProps.bar} 
        data={props.data}
      />
    )}
  />
)

QueryRenderer 本身已经是一个 React 组件,您通常不必将它包装在类组件渲染中。

List 现在是一个纯函数组件,当它接收到新的 props (parentProps) 时,它将重新渲染,因此 Table 将被重新渲染

于 2018-01-24T15:37:18.440 回答