如何让 QueryRenderer 传播父道具更改?
Posted
技术标签:
【中文标题】如何让 QueryRenderer 传播父道具更改?【英文标题】:How to get the QueryRenderer to propagate parent prop changes? 【发布时间】: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
/>
有什么想法吗?
【问题讨论】:
【参考方案1】:删除你的 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 也会重新渲染
【讨论】:
以上是关于如何让 QueryRenderer 传播父道具更改?的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL / Relay - 是不是需要在主 QueryRenderer 中查询所有表?
如何使用 Relay QueryRenderer 道具更新状态
中继 QueryRenderer fragmentContainer 传递的道具与服务器响应不同,因为 id 冲突
ReactJS setState 更改不会从父组件传播到子组件[重复]