optional
optional

Reputation: 2782

Using asynchronous obtained ListItem components from the state of a React component in Material-UI List for React

The List component from http://www.material-ui.com/#/components/list does not render asynchronous received elements, what to do?

The way I use my list in the render() method of the component:

<List children={this.state.elements} />

Filling my state:

constructor(props) {
    super(props);
    this.state = {elements: []};
}

async componentDidMount() {
    this.setState({elements: this.getInitialState()});
}

async getInitialState() {
      var elements = [];
      const response = await fetch('api/endpoint/elements');
      const result = await response.json();
      if (result.status = "success") {
          elements.push(<ListItem primaryText="Dummy Data" />);
      }
      return elements;
  }

Upvotes: 0

Views: 1245

Answers (2)

Sergey Orlov
Sergey Orlov

Reputation: 331

You need to await getInitialState in componentDidMount.

async componentDidMount() {
    const state = await this.getInitialState();
    this.setState({elements: state});
}

If you want to do something after setting the state use this Async wrapper of setState and await it

  setStateAsync(state) {
    return new Promise((resolve) => {
      this.setState(state, resolve)
    });
  }

Upvotes: 1

Patrick
Patrick

Reputation: 3367

The concept is okay and should work.

componentDidMount is the place to add async logic for small apps(see sagas, redux etc. for bigger apps).

your problem is that setState is not an async function, so the component's state cannot be properly set.

simply move all the ajax logic componentDidMount, when the ajax resolves, modify the state.

I never tried it with await, so I can't be sure it works with that, but it 100% works with Promises (fetch for example)

a tiny pseudo code :

componentDidMount(){
   //jquery's POST function, just as an example
   $.post(url).then(() => {
      this.setState({dataLoaded:true});
   });
}

Upvotes: 1

Related Questions