子组件可以访问其包含组件的方法吗?

时间:2018-08-20 19:09:36

标签: javascript reactjs methods

我看到了与此类似的问题,但是他们通常谈论的是父母访问子组件的方法或通过prop传递方法。我的问题是在特定情况下使用props.children,并且让任何子组件都能够在呈现props.children的父对象上调用方法。

我试图实现的简化示例:

class WrapperComponent extends React.Component {

constructor(props){
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this)
}

handleInputChange(e){
    console.log("neat, you changed the input")
}

render() {
    return (
        <form>
            {this.props.children}
        </form>
    )
  }
}

调用该组件并将子级作为道具传递的组件。

const Component = (props) => {
return(
    <WrapperComponent>
        <div className="form-group" >
            <label>
                <div>Text</div>
                <input onChange={this.handleInputChange} type={"text"}/>
            </label>
        </div>
    </WrapperComponent>
)
}

这个想法是,我可以渲染一个具有一定逻辑的组件,并将元素作为子元素传递给该组件以进行渲染,而且props.children然后可以在包装器中调用所述逻辑,所以我可以在不同的用例中传递不同的子代,但是处理方式将始终相同。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以使用一些内置的React好东西克隆您的元素并为其添加新的道具:

class WrapperComponent extends React.Component {

constructor(props){
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this)
}

handleInputChange(e){
    console.log("neat, you changed the input")
}

render() {
    return (
        <form>
            {React.Children.map(
                this.props.children, 
                el => React.cloneElement(el, {onInputChange: this.handleInputChange})
            )}
        </form>
    )
  }
}

然后(删除WrapperComponent):

const Component = (props) => {
  return(
        <div className="form-group" >
            <label>
                <div>Text</div>
                <input onChange={props.onInputChange} type={"text"}/>
            </label>
        </div>
  )
}

然后:

ReactDOM.render(
    <WrapperComponent><Component /></WrapperComponent>,
    document.getElementById('root')
)

答案 1 :(得分:1)

是的,有一种方法,但是它并不简单,您可能需要考虑另一种方法。

为了使子级组件能够访问任意父级的方法,父级必须重写子级的props。可以使用父级React.cloneElement函数中的render()来完成此操作。在您的示例中:

class WrapperComponent extends React.Component {

constructor(props){
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this)
}

handleInputChange(e){
    console.log("neat, you changed the input")
}

render() {
    return (
        <form>
            {React.Children.map(this.props.children, child => (
                React.cloneElement(child, {handleInputChange: this.handleInputChange}
            )}
        </form>
    )
  }
}

然后,您可以通过this.props.handleInputChange访问子级中的方法。