使用prop将子组件数据传递给父组件

时间:2019-04-23 13:52:41

标签: javascript reactjs

我对ReactJS完全陌生。我有一个组件(组件A),我想单击一个按钮并使用AJAX调用从API中获取令牌。提取成功后,我需要将其传递到另一个组件(组件B)并有条件地呈现(https://reactjs.org/docs/conditional-rendering.html)。

组件A和B都嵌套在一个父组件中,应该有条件地呈现。

class Parent extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <ComponentA />
        or
        <ComponentB>
      </div>
    );
  }
}

预期结果:

ComponentA应该在其内部获取令牌并传递给其Parent,并通过通知替换ComponentA并呈现ComponentB来实现。

我尝试过的代码:

我从这里举个例子:https://codepen.io/gaearon/pen/QKzAgB?editors=0010How to pass data from child component to its parent in ReactJS?并编写了以下代码。

class ComponentA extends React.Component {
    constructor(props){
      super(props);
      this.handleGenerateToken = this.handleGenerateToken.bind(this);
    }

    handleGenerateToken(){
      console.log("gen token");
      axios({ 
        method: 'post',
        url: 'https://<token_url>',
        mode: 'no-cors'
      }).then((result) => {
        if(result.status === 200){
          console.log({token:result.data});
          this.props.onGenerateToken({token:result.data}); //it fails here
        }else{
          console.log("Error generating token. Status code: " + result.status);
        }
      });
    }

    render(){
      return(
        <div>
          <div id="details" className="div-center">
            some ui
            <div>
            <a id="btnStart" onClick={this.handleGenerateToken} className="waves-effect waves-light btn secondary-content">Start</a>
            <a id="btnReset" className="waves-effect waves-grey btn blue-grey lighten-5 black-text outline secondary-content">Reset</a>
            </div>
          </div>
        </div>
      );
    }
}

问题是我获得了令牌,但是无法使用this.props将其设置为道具。我得到以下提示,看来this无法访问。

  

未捕获(承诺)TypeError:_this4.props.onGenerateToken不是   功能       在:182:26

我尝试创建一个额外的变量_self,并在AJAX调用的this范围之外分配Promise,但这没用。

我不确定我是否正确执行了此操作。请让我知道是否可以详细解释。

3 个答案:

答案 0 :(得分:1)

一个简单的例子:

<ComponentA/>成为您的组成部分:

 handleGenerateToken(){
  console.log("gen token");
  axios({ 
    method: 'post',
    url: 'https://<token_url>',
    mode: 'no-cors'
  }).then((result) => {
    if(result.status === 200){
      console.log({token:result.data});
      this.props.onGenerateToken({token:result.data}); //it will have a handler in wrapper(parent) component
    }else{
      console.log("Error generating token. Status code: " + result.status);
    }
  });
}

<Parent/>成为包裹<ComponentA/><ComponentB/>的组件。根据状态中定义的布尔型标志isTokenAvailable有条件地渲染组件

<Parent/>的render方法中:

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isTokenAvailable: false,
            token:null
        };
    }

    render() {
        const isTokenAvailable = this.state.isTokenAvailable;
        return (
            <div>
                {isTokenAvailable ? (
                    <ComponentB />
                ) : (
                    <ComponentA
                        onGenerateToken={(token) => {
                            this.setState({ isTokenAvailable: true, token });
                        }}
                    />
                )}
            </div>
        );
    }
}

答案 1 :(得分:0)

this.emit(name, ...)更改为this.handleGenerateToken或将this.handleGenerateToken()更改为handleGenerateToken(){

而不是更改道具,只需使用state:)

handleGenerateToken = () => {

然后只是

state = { token: undefined };
constructor(props){
      super(props);
      this.handleGenerateToken = this.handleGenerateToken.bind(this);
}

然后您可以有条件地渲染它

this.setstate({token:result.data});

答案 2 :(得分:0)

react doc

更改

handleGenerateToken(){

handleGenerateToken = () => {