Reactjs 在父函数中存储对子函数的引用

Reactjs 在父函数中存储对子函数的引用,reactjs,Reactjs,我有一个有趣的用例,用于存储对属于子组件的函数的引用。另外,我使用React的新上下文API将数据传递给深度嵌套的子组件 我已经找到了许多解决类似问题的其他答案,但它们与我的用例不太匹配。见和 这是一个高层次的问题: 名为的提供程序组件包含传递给所有组件(即使用者的组件)的逻辑和状态 Child组件接收一个verify道具,该道具本质上是一个针对特定子组件的验证函数。每次调用verify都会根据父项的传入状态更改生成一个verificationResult 重要的是,必须通知所有其他子组件或了解

我有一个有趣的用例,用于存储对属于子组件的函数的引用。另外,我使用React的新上下文API将数据传递给深度嵌套的子组件

我已经找到了许多解决类似问题的其他答案,但它们与我的用例不太匹配。见和

这是一个高层次的问题:

  • 名为
    提供程序
    组件包含传递给所有
    组件(即
    使用者
    的组件)的逻辑和状态
  • Child
    组件接收一个
    verify
    道具,该道具本质上是一个针对特定
    子组件的验证函数。每次调用
    verify
    都会根据
    父项的传入状态更改生成一个
    verificationResult
  • 重要的是,必须通知所有其他
    组件或了解其同级生成的每个
    验证结果的结果
  • 为了让事情变得更加有趣,我不希望将每个子级的所谓的
    验证结果
    存储在父级状态(如果不需要的话),因为它本质上是派生状态,可以在
    父级
    渲染()
    中计算
  • 解决方案1:

    将每个子项的
    验证结果
    存储在
    父项中
    。这可以通过等待每个
    组件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>
      )
    }