2

I've some trouble while using React for my first time. I wrote a simple class as follow in my project :

import React, { Component } from 'react';
import axios from 'axios';
import logo from './logo.svg';
import './App.css';

class FigosTest extends React.Component {
  state = {
    provider: 'unknown',
    date: 'sometime'
  };

  componentDidMount() {
    axios.get('x.com/some_api')
      .then(res => {
        console.log(res.data.provider);
        console.log(res.data.date);
        this.setState(this.setState(res.data));
        console.log("After");
        console.log(this.state.provider);
        console.log(this.state.date);
      });
  }

  render() {
    return this.provider || 'undefined';
  }
}

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Result: <FigosTest/>
          </p>
        </header>
      </div>
    );
  }
}

export default App;

I want to get and display some data from the API I'm asking. I used to do this a call to this API that will render me an object containing only provider and date labels.

Let's say I want to display the provider. I see with console.log that my component achieve to query the API, and to return my values.

My problem is that the component wouldn't update after this operation.

I tried to callback App.render, to use schouldComponentUpdate, and in others posts, I noticed that everybody use ReactDOM.render(). What is it ? How to use it ?

Regards.

Pyrrha
  • 159
  • 2
  • 12

3 Answers3

6

There are a few issues, one or more of which are probably the problem (particularly #4):

  1. State changes are asynchronous. You won't see the changes to state on this.state immediately after calling it. If you need to see the changes, use the callback (the second argument to setState).

  2. setState has no return value, so it doesn't make sense to call setState with the return value of setState. I wouldn't think that was the problem, but this:

    this.setState(this.setState(res.data));
    

    should be

    this.setState(res.data);
    
  3. The documentation doesn't say that the render method can return undefined. So it's not defined (no pun!) if you return undefined, as you're doing.

  4. In your render, you're using this.provider. If provider is provided by res.data, you should be using this.state.provider.

You mentioned looking at various other methods (componentShouldUpdate, etc.), but there's no need in this case. You're kicking off your async process in the right place (componentDidMount), and setting state in response to that completing (which is also correct, though see #1 and #2 above).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    The more impactant was the #4, indeed. For the #3, it was only in textual, so it's only for displaying, not for the `undefined` value. And I correct the #2. Thanks for your help. – Pyrrha Dec 11 '18 at 09:30
1

You can also confirm if your state has updated or not.

this.setState(res.data, () => console.log(this.state));
jame3030
  • 36
  • 3
-1

Please see below.

import React, { Component } from 'react';
import axios from 'axios';
import logo from './logo.svg';
import './App.css';

class FigosTest extends React.Component {
  state = {
    provider: 'unknown',
    date: 'sometime'
  };

  componentDidMount() {
    axios.get('x.com/some_api')
      .then(res => {
        console.log(res.data.provider);
        console.log(res.data.date);
        this.setState(res.data, () => {
          console.log("After");
          console.log(this.state.provider);
          console.log(this.state.date);
        });
      });
  }

  render() {
    return this.provider || 'undefined';
  }
}

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Result: <FigosTest/>
          </p>
        </header>
      </div>
    );
  }
}

export default App;
  • 4
    Code dumps are not *useful* answers. Say what you changed, and why. Also, this doesn't fix the majority of the problems, and if you use Stack Snippets, the snippet should be *runnable* (this one isn't, it throws a syntax error). Stack Snippets do support React, including JSX; [here's how to do one](http://meta.stackoverflow.com/questions/338537/). – T.J. Crowder Dec 10 '18 at 16:53