React - 触发子组件

时间:2018-02-27 13:36:00

标签: javascript reactjs

谷歌在这个讨论很多的主题上有很多,但是,我无法找到解决问题的明确方法(可能很常见)。

我有一个父组件和一个子组件(见下图),其中子组件生成要存储在某处的值,父组件有一个触发存储操作的按钮:

enter image description here

在这种情况下,父母不希望设置或修改任何子道具或州,而是从中获取一些价值。

对我而言,似乎最好的方法是使用ref并调用子组件方法来获取值;但我正在努力避免使用ref,正如任何反应文档所暗示的那样。

这是一个用例,我最好使用refs,还是我错过了更好的方法?在这种情况下使用refs有什么缺点?

2 个答案:

答案 0 :(得分:1)

我个人认为使用refs没有任何问题。它实际上适合您的情况,因为它是按需请求。但是您可以使用文档中描述的Lifting State Up机制。

基本上你会使用回调机制。每次子组件获得输入时,您将调用onChangeInput(input),这是在父组件中实现的。在那里你可以存储它并使用它。

例如,在按钮单击时生成随机数的子组件,以及使用最新项生成某项内容的父组件会从子项生成值:

class Parent extends Component {

    constructor(props) {
        super(props);
        this.childData = null;
    }

    render() {
        return (
            <div>
                <Child onChange={(data) => this.childData = data}/>
                <button onClick={() => console.log("data to be consumed", this.childData)}>Consume Data</button>
            </div>
        )
    }
}

const Child = (props) => (
    <button onClick={() => props.onChange(Math.random())}>Produce Data</button>
);

答案 1 :(得分:1)

  • 在父级中设置初始状态,以便从孩子那里获取内容。在这种情况下,temp将存储来自child的数据。
  • 在Parent组件中创建一个getter函数,该函数将接受一个参数。此参数是您尝试传递给父级的数据。
  • 现在你需要一些东西来触发getter函数,所以出于演示的目的,我只是添加了一个按钮,当它被点击时,它会将数据从子节点传递给父节点,它将在父节点中呈现。
  • 现在,当点击按钮时,它将呈现Hello,这是存储在子状态内的内容。

    class Parent extends Component {
     constructor(props) {
     super(props)
      this.state = {
       temp:'',
      }
     }
    
     getFromChild = (data) => {
      this.setState({ temp:data })
     }
     render() {
      return (
        <div>
         <div> THIS IS FROM CHILD: {this.state.temp} </div>
         <Child getFromChild={this.getFromChild}/>
        </div>
      )
     }
    }
    
    class Child extends Component {
     constructor(props) {
     super(props)
      this.state = {
       data:'hello',
      }
     }
     render() {
      return( 
       <button onClick={() => this.props.getFromChild(this.state.data)}> view data </button>
      )
     }  
    }
    

第2部分

  • 由于按钮在父母中,我们需要一种让孩子知道的方法 是否在单击该按钮时传递数据 为什么我们在州内宣布pass
  • 点击按钮后,pass现在为真。
  • 将调用子组件this.props.getFromChild(this.state.data)内部。

     class Parent extends Component {
      constructor(props) {
        super(props);
        this.state = {
          temp: "",
          pass: false
        };
      }
    
      getFromChild = data => {
        this.setState({ temp: data });
      };
      passData = () => {
        this.setState({ pass: true });
      };
      render() {
        console.log(this.state.pass);
        return (
          <div>
            <div>
              {" "}
              THIS IS PARENT COMPONENTS STATE:{" "}
              {!this.state.temp && <div> NOTHING YET </div>}
              {this.state.temp}{" "}
            </div>
            <button onClick={() => this.passData()}> Pass the data </button>
            <Child
              temp={this.state.temp}
              pass={this.state.pass}
              getFromChild={this.getFromChild}
            />
          </div>
        );
      }
    }
    
      class Child extends Component {
        constructor(props) {
        super(props);
        this.state = {
          data: "hello"
        };
      }
      render() {
        if (this.props.pass & (this.props.temp !== this.state.data)) {
          this.props.getFromChild(this.state.data);
        }
        return (
          <div>
            {" "}
            This is the child component <br /> state::: data: {this.state.data}{" "}
          </div>
        );
      }
    }
    render(<Parent />, document.getElementById("root"));
    

    codesandbox