简体   繁体   中英

Passing child component data to parent using props

I am completely new to ReactJS. I have a component (Component A) where I want to click a button and fetch a token from an API using AJAX call. Once the fetch is successful I need to pass it to another component (Component B) and render it conditionally ( https://reactjs.org/docs/conditional-rendering.html ).

Both Component A and B are nested within a single parent component and should render conditionally.

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

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

Expected result:

ComponentA should fetch the token within itself and pass to its Parent , there by notifying to replace ComponentA and render ComponentB .

Code I tried:

I took an example from here: https://codepen.io/gaearon/pen/QKzAgB?editors=0010 and How to pass data from child component to its parent in ReactJS? and wrote the below code.

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>
      );
    }
}

Problem is I get the token but unable to set it to the props using this.props . I get below which seems like this is not accessible.

Uncaught (in promise) TypeError: _this4.props.onGenerateToken is not a function at :182:26

I tried creating an extra variable _self and assign this outside the Promise scope of the AJAX call but that didn't work.

I am not sure if I am doing this correctly. Please let me know if I can explain in more detail.

A simple example :

Let <ComponentA/> be your component:

 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);
    }
  });
}

Let <Parent/> be the component you have wrapped this <ComponentA/> and <ComponentB/> . Conditionally render components on basis of boolean like flag isTokenAvailable defined in state

In <Parent/> 's render method :

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>
        );
    }
}

Change this.handleGenerateToken to this.handleGenerateToken() or handleGenerateToken(){ to handleGenerateToken = () => {

And instead of changing props, just use state :)

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

and then just simply

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

Then you can render it conditionaly

render(){
if(this.state.token === undefined){
   return <Text>Oh, Token is undefined</Text>
}
   return <Text>Token is defined</Text>
}

react doc

change

handleGenerateToken(){

to

handleGenerateToken = () => {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM