使用 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
组件的初始渲染foo
并bar
正确设置,但是如果foo
或bar
之后发生更改,新值不会传播到Table
组件,因为QueryRenderer
.
由于只有在for更改时不会触发该方法的QueryRenderer
唯一重新渲染,因为没有看到需要它,因此组件保留旧的 prop 值。variables
SomeQuery
renderQuery
QueryRenderer
Table
由于将 props 传递给孩子是一项非常常见的任务,因此忽略父母 props 更改的事实QueryRenderer
造成了很大的问题。我一直想知道解决方案可能是什么,并提出了一些选择:
- 使用Context绕过此行为。然而,除非你有充分的理由,否则通常不鼓励使用 Context + 感觉就像是一种肮脏的黑客来规避这个问题。
- 强制
QueryRenderer
重新渲染与readyState
以前相同。这也许可以实现,refs
但您需要自己检查何时重新渲染。 - 不知何故
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}
/>
有任何想法吗?