Reactjs 在父函数中存储对子函数的引用
我有一个有趣的用例,用于存储对属于子组件的函数的引用。另外,我使用React的新上下文API将数据传递给深度嵌套的子组件 我已经找到了许多解决类似问题的其他答案,但它们与我的用例不太匹配。见和 这是一个高层次的问题:Reactjs 在父函数中存储对子函数的引用,reactjs,Reactjs,我有一个有趣的用例,用于存储对属于子组件的函数的引用。另外,我使用React的新上下文API将数据传递给深度嵌套的子组件 我已经找到了许多解决类似问题的其他答案,但它们与我的用例不太匹配。见和 这是一个高层次的问题: 名为的提供程序组件包含传递给所有组件(即使用者的组件)的逻辑和状态 Child组件接收一个verify道具,该道具本质上是一个针对特定子组件的验证函数。每次调用verify都会根据父项的传入状态更改生成一个verificationResult 重要的是,必须通知所有其他子组件或了解
的提供程序
组件包含传递给所有
组件(即使用者
的组件)的逻辑和状态Child
组件接收一个verify
道具,该道具本质上是一个针对特定子组件的验证函数。每次调用verify
都会根据父项的传入状态更改生成一个verificationResult
子
组件或了解其同级生成的每个验证结果的结果
验证结果
存储在父级状态(如果不需要的话),因为它本质上是派生状态,可以在父级
渲染()
中计算验证结果
存储在父项中
。这可以通过等待每个子的组件diddupdate()
中的相关值发生更改来实现,如下所示:
// Child.js
...
componentDidUpdate(pp) {
const { hash, value, verify, setVerificationResult } = this.props
// this check is a little more involved but
// the next line captures the gist of it.
if(pp.value[pp.hash] !== value[hash]) {
setVerificationResult(hash, verify(value[hash], value))
}
}
...
// Parent.js
...
setVerificationResult(hash, result) {
this.setState(({ verificationResults }) => ({
...verificationResults, [hash]: result
}))
}
...
注意:
this.props.value
和this.props.setVerificationResult
是从作为上下文提供者的父级
接收的,而
this.props.hash
和this.props.verify
直接传递给子组件
this.props.hash
获取此特定子对象需要知道的值的部分
// MyComponent.js
render() {
return (
...
<Child
hash="someHash"
verify={(value, allValues) => {
return value === 42 && allValues["anotherHash"] === 42
}}
render={({ verificationResults }) => (
<pre>{JSON.stringify(verificationResults["someHash"], null, ' ')}</pre>
)}
/>
...
)
注意,在第二个解决方案中,我没有存储任何额外的状态,因为它只是动态计算的。但是,我在子组件上存储对函数的引用
有人能告诉我为什么不使用解决方案2吗?关于如何实现这一点,有其他建议吗
补充说明:
- 为什么不直接将verify函数传递给父级呢?我可以这样做,但这并不是一个非常干净的API
- 您可以假设我正在卸载时执行必要的清理,等等
- 问题比这里显示的更复杂-事实上,有深度嵌套的使用者与“本地”提供者通信,该提供者“拆分”值和逻辑,直到它们到达所谓的叶组件,而“主”提供者被用作根节点,包含组件层次结构中的所有组件状态和逻辑
您能否澄清您所说的“必须通知所有其他子组件或了解其同级生成的每个验证结果”是什么意思。从某种意义上说,为什么需要通知他们?有没有办法使用某种服务通知他们?(某种通量型架构)关于为什么不使用第二种解决方案的第二个问题:老实说,你可以这么做,但这不是推荐的,也不是反应方式。我的意思是,react是以某种心态创建的,在这种心态下,应用程序的所有更改都是数据驱动的。如果一切都是数据驱动的,那么父组件不应该能够独立地让子组件做一些事情,它应该做的是更改数据,并告诉子组件看看这些数据更改是否适用于它们。这是为了使一切都有条理,所有子组件逻辑和事件发生时的逻辑都在子组件中。我希望这是纯粹的反应。尽可能少的依赖项-这对于状态管理库来说是双倍的。2.也许notify是个错误的词。其核心问题是,子对象上的道具需要更改父对象中的状态,并且该状态位需要在所有消费者中可用。然而,当您想到验证(在本例中,我称之为验证)时,验证是某个或多个值的当前状态的产物。它不需要存储在状态中(这是我选择解决方案2的部分原因)。您可以自己实现flux,但是如果您只是因为这个原因而使用它,可能会有点过头。归根结底,这是一个只有你才能做出判断的问题,因为你拥有关于你正在建设的项目类型的所有最多信息。
// Child.js
...
componentDidMount() {
const { register } = this.props
register(this.verify)
}
verify(values) {
const { hash, verify } = this.props
return { [hash]: verify(values[hash], values) }
}
...
// Parent.js
constructor(props)
super(props)
this.tests = []
this.state = {
value: null,
// other initial state
}
...
}
register(verifyFunc) {
this.tests.push(verifyFunc)
}
render() {
const { value } = this.sate
let result = {}
this.tests.forEach(test => result = { ...result, ...test(value) })
return (
<Provider
value={{
...this.state,
verificationResults: result,
register: this.register,
// other things...
}}
>
{this.props.children}
</Provider>
)
}