如何将属性从有状态组件传递到 HOC 中使用的事件处理程序来包装子组件?

How can I pass attributes from a stateful component to an event handler used in an HOC wrapping a child component?

我正在使用一个框架,在该框架中我必须将事件处理程序传递到 HOC 中,该 HOC 包装了有状态页面组件的一个子组件。

<Page>
    <HOC onClick={fn}>
        <PageColumn>
        </PageColumn>
    </HOC>
</Page>

我的有状态页面组件中有一个函数依赖于页面的状态和属性。我必须使用包装页面子组件的 HOC。在此 HOC 中,我必须调用依赖于 Page 组件状态的 onClick 方法。

到目前为止,我已经尝试传递对 this.state 的引用以便在 HOC 中使用页面状态,并且我已经尝试传递在父状态中分配了我需要的值的道具.在 onClick fn 中,无论我使用 this.state 还是 this.props 引用必要的属性,我都会得到错误:

 cannot read property '<attribute>' of undefined

我怎样才能成功实施这个模式?

您的代码没有太多值得研究的地方。 我注意到您将 HOC 用作组件,但通常 hoc 是向组件添加内容的函数。

通常 hoc 是这样工作的:

EnrichedComponent = hoc(选项)(BaseComponent);

示例:react-redux connect hoc 函数

这种方法应该有效:

// render Page somewhere
const App = () => (
  <Page/>
)

// let Page component render the PageColumn component
class Page extends React.Component {
  handleClick() {
    // I can access page state and props
    const {
      state: { foo },
      props: { bar },
    } = this;

    console.log(foo, bar);
  }

  render() {
    return (
      <PageColumn onClick={this.handleClick} />
    )
  }
}

// wrap component with HOC
const PageColumn = hoc()(() => {
  return (
    <div>...</div>
  )
});

看看下面的代码。基本上,您想在顶级组件中创建函数并将其绑定到构造函数中的 this 。然后将它 作为 属性 传递给您的子组件(即没有参数列表,没有函数语法,只是 `this.myFunc')。

在子组件中,在onClick事件中,调用该函数并传入您的参数。使用父函数的属性的名称来调用函数。因此,例如,这里仍然是 this.props.myFunc,但是如果 <Page /> 有这个表达式:mySpecialFunc={this.myFunc} 你会这样调用 <HOC onClick={(prm1,prm2,prm3) => this.props.mySpecialFunc(prm1,prm2,prm3)} />

<Page />中:

constructor(){
   //regular constructor code

   this.myFunc = this.myFunc.bind(this);
}

myFunc(prm1, prm2, prm3){\
   //function code
   //
   this.setState({
      myFuncState: "newValue",
      //additional code
   });
}

render(){
    return (
        <Page>
            <HOC myFunc={this.myFunc}>
                <PageColumn />
            </HOC>
        </Page>
    )
}

<HOC />中:

render(){
    prm1 = "someValue1";
    prm2 = "someValue2";
    prm3 = "someValue3";
    return (
        <div className="HOC" onClick={(prm1,prm2,prm3) => this.props.myFunc(prm1,prm2,prm3)}>
    )
}

参数说明: 上面的代码是针对你的所有参数都在一个地方的情况(在这种情况下,直接子组件)。有时它们分布在父组件、子组件、孙组件等之间。在这种情况下,您需要在每个组件中通用地声明参数,[​​=39=]在组件祖先链中向下移动时传递相关参数。例如:

class Parent extends React.Component{
    constructor(){
        //normal render code
        this.passedFunc = this.passedFunc.bind(this);
    }

    passedFunc(prm1,prm2){
        //function code
        this.setState({
            a: val1,
            b: val2,
            //etc.
        })
    }

    render(){
        return (
            <Child passedFunc={this.passedFunc}
        )
    }  
}

class Child extends React.Component{
    //other relevant code

    render(){
        let val1 = "foo";

        return (
            //we're passing prm1 into the func as val1. <Child /> doesn't know what prm2 is so we're keeping that generic and letting <GrandChild /> handle it   
            <GrandChild passedFunc={(prm1, prm2) => this.props.passedFunc(val1, prm2)}
        )
    }
}

class GrandChild extends React.Component{
    //other relevant code

    render(){
        let val2 = "bar";

        return (
            //<GrandChild /> doesn't know what prm1 is, but it knows that prm2 is val2, so it's passing in prm2 as val2 and leaving prm1 generic so <Child /> can handle it
            <div passedFunc={(prm1, prm2) => this.props.passedFunc(prm1, val2)}
        )
}

如您所见,每个组件都将参数向上传递给它们的父组件,并对它们不知道的参数使用通用参数名称。最后,父组件接收所有参数并能够在函数中使用它们。如果链中有一个不需要设置任何参数的中间人组件,例如一个名为 <Child /> 和 '' 之间的名为 <InBetween /> 的组件,您可以简单地通过它传递函数名称组件作为一个简单的 属性,像这样:

<InBetween passedFunc={this.props.passedFunc} />

在链中其上方或下方的组件中设置的任何参数都将保持不变。