如何从父组件调用`this.props.children`函数?

时间:2017-09-12 09:38:53

标签: reactjs ecmascript-6 components

有一些问题是相对的,但完全不同

Call child method from parent

Call child function from parent component in React Native

https://github.com/kriasoft/react-starter-kit/issues/909

他们都需要在Child文件中导入Parent

但是如何将ref设置为this.props.children ???

目的

我想在Child中调用Parent方法,Parent是一个常见的包装器,需要具有特定功能的ChildChild是动态的,

  1. class Child extends React.Component {
      method() {
        alert(1111);
      }
      render() {
    
        return (
          <div>
            ....
          </div>
        );
      }
    }
    
  2. import React from 'react'
    // can not import Child here
    // import Child from './Child'  
    
    class Parent extends React.Component {
      onClick = () => {
        this.props.children.method() // do stuff, but not work
      }
      render() {
    
        const {children} = this.props;
        return (
          <div>
            {children}
            <button onClick={this.onClick}></button>
          </div>
        );
      }
    }
    
  3. index.js

    <Parent>
       <Child/ >
    </Parent>
    
  4. Parent只能Child访问this.props.children,我不希望将Child方法传递给Parent索引.js,或在index.js中定义Child的方法。

    换句话说:

    1. Child保留所有Child代码。(例如,提交逻辑的表单)

    2. Parent是一个常见的包装器。 (例如,用于包装表单的对话框)

    3. Index.js不关心他们

    4. 有什么想法吗?

3 个答案:

答案 0 :(得分:2)

感谢@Panther的评论,我使用React.cloneElement来解决这个问题:

  1. class Child extends React.Component {
    
      handleSubmit() {
        //...
      }
    
      render() {
    
        return (
          <div>
            ....
          </div>
        );
      }
    }
    
  2. import React from 'react'
    
    class Parent extends React.Component {
    
      onClick() {
        // fist child need have handleSubmit
        this.refs.child0.handleSubmit()
        this.toggleDialog()
      }
    
      render() {
    
        const children = React.Children.map(this.props.children,
          (child, index) => React.cloneElement(child, {
            ref : `child${index}`
          })
         );
    
        return (
            <div>
              <DialogContent>
                {children}
              </DialogContent>
            <button onClick={this.onClick}></button>
          </div>
        );
      }
    }
    
  3. index.js

    <Parent>
       <Child/ >
    </Parent>
    

答案 1 :(得分:1)

建议不要使用refs。你可以使用componentWillReceiveProps 处理来自父级的道具变化,或者您可以使用shouldComponentUpdate来处理道具或州的变化。

但是,在shouldComponentUpdate中,您可以轻松控制子组件的渲染序列。

答案 2 :(得分:0)

您可以这样做:(代码已经过测试!)

Parent.js

class Parent extends React.Component {

  onClick() {
    // take notice to the array's index "children[0]" (you can also loop the children array)
    this.refs.wrapper.children[0].method();
  }

  render() {
    const {children} = this.props;
    // you must put the ref="wrapper" to locate the container element wrapping all the children
    return (
      <div ref="wrapper">
        {children}
        <button onClick={this.onClick.bind(this)}>click</button>
      </div>
    );
  }
}

Child.js(无变化)

class Child extends React.Component {
  method() {
    alert(1111);
  }
  render() {

    return (
      <div>
        ....
      </div>
    );
  }
}

index.js :(无变化)

<Parent>
   <Child/ >
</Parent>