【发布时间】:2018-07-02 13:02:03
【问题描述】:
使用 Relay Modern v.1.4.1,考虑以下List 组件。
它需要两个 props foo 和 bar 并使用这些 props 和 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 组件的初始渲染,foo 和 bar 设置正确,但是如果 foo 或 bar 之后发生更改,则新值不会传播到 Table 组件,因为QueryRenderer.
由于QueryRenderer 仅在variables 更改SomeQuery 时才会重新渲染,因此renderQuery 方法没有被触发,因为QueryRenderer 认为不需要它,所以Table 组件保留使用旧的道具值。
由于将 props 传递给孩子是一项非常常见的任务,QueryRenderer 忽略父母的 prop 更改这一事实造成了很大的问题。我一直想知道解决方案可能是什么,并提出了一些选择:
- 使用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}
/>
有什么想法吗?
【问题讨论】:
标签: reactjs relayjs relay relaymodern