如何让QueryRenderer传播父道具更改?

时间:2018-01-23 16:17:20

标签: reactjs relayjs relay relaymodern

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

它需要两个道具foobar,并使用这些道具和GraphQL查询的结果呈现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组件

由于QueryRenderer variables SomeQuery更改了renderQuery方法,QueryRenderer仅重新呈现,因为Table没有看到需要对于它,所以QueryRenderer组件保留旧的道具值。

因为向父母传递道具是一项非常普遍的任务,因为QueryRenderer对父母的道具变化一无所知是一个很大的问题。我一直在想这可能是什么解决方案,并提出了一些选择:

  1. 使用Context来绕过此行为。然而,通常不鼓励使用Context,除非你有充分的理由+它感觉就像是一个肮脏的黑客来规避这个问题。
  2. 强制readyState使用与以前相同的refs重新渲染。这可能是使用QueryRenderer实现的,但您需要自己检查何时重新渲染。
  3. 以某种方式让QueryRenderer关心我的道具。这显然是正确的方法,但我在文档中找不到允许这样做的任何内容,所以我需要做一些事情,比如从QueryRenderer创建一个更高阶的组件,或者实现这个的子类。品行。
  4. 理想情况下,我希望有一种原生方式让<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}
    />
    

    Python

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

删除您的类组件并将上述代码更改为:

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组件,你通常不必将它包装在一个Component render类中。

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