简体   繁体   中英

undefined React JS variable

this is my first time coding in Javascript/React JS so I'm not sure what is wrong here. getLicensees() send a GET request it my API and returns all the licensees. This works so far, also the console logs are working and printing the correct value.

constructor(props) {
super(props);

this.state = {licensees: []};

let licenseeResponse = LicensingService.getLicensees()
  .then(licensees => {
    this.state.licensees = licensees;
    console.log("component", licensees);
    console.log(licensees[0].city);
  });
}

I'm trying to generate a table out of all the information's inside my licensees object. But I can't use this.state.licensees[0].city inside my render() method.

render() {
return (
  <main id="content">
    <div id="head">
      <h4 className="headline">
        Liste aller Lizenznehmer
      </h4>

      <div className="licenseeTable">
        <table>
          <tr>
            <th>Lizenz nehmer</th>
            <th>Aktuelles Zertifikat</th>
            <th>Details</th>
          </tr>
          <tr>
            <td>{this.state.licensees[0].city}</td>
            <td>test2</td>
            <td>test3</td>
          </tr>
        </table>
      </div>
    </div>
  </main>
);
}

how can I do this properly?

--My solution:

componentDidMount() {
console.log('component did mount..', this);
LicensingService.getLicensees()
  .then(licensees => {
    this.setState({licensees});
    console.log(licensees);
  });
}

...

{
            this.state.licensees.map(license => {
              return <tr>
                <td>{license.company}</td>
                <td>{license.testCertificate.toString()}</td>
                <td>{license.city}</td>
              </tr>
            })
          }

this.setState({licensees}) is the correct way to assign value to the state object.

The problem is that although you have your API request in constructor, it will return a response only after the render cycle and since you are directly mutating state in the resolved promise, a re-render is not called.

What you need to do is to have the API call in componentDidMount lifecycle method and update your state using setState

constructor(props) {
   super(props);

   this.state = {licensees: []};

}

componentDidMount() {
    LicensingService.getLicensees()
      .then(licensees => {
        this.setState({licensees});
        console.log("component", licensees);
        console.log(licensees[0].city);
    });
}

First you want to move the api call to componentDidMount instead of doing it in a constructor, doing so wont work as your component would already have rendered before you get the data.

Then you need to use setState to cause your render function to be called so that the updated value is displayed. like this :

this.setState({licensees}); instead of mutating the state directly like

this.state.licensees = licensees;

read more here Using State Correctly

You would also want to wait for the value untilll you try to access it so you will have to make this change in your render as well Instead of this :

<td>{this.state.licensees[0].city}</td>

do this

{this.state.licensees && <td>{this.state.licensees[0].city}</td>} //only render when you have the value in the state.

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