0

I am new in React and trying to call multiple api call within componentDidMount function.

My code is

componentDidMount() {

        Promise.all([
            axios.get(<url1>),
            axios.get(<url2>)
            ]).then(([res1, res2]) => {
            // call setState here
            const users =  res1.data.users;
            this.setState({ users: users});
            const banks  =  res2.data.banks;
            this.setState({ banks: banks});
            console.log("Users")
            console.log(users) // It works
            console.log("Banks")
            console.log(banks) // It works
        })

    }

render() {
        console.log(this.state.users.length) // Gives length
        console.log(this.state.banks.length) // Gives undefined
        return (
            <div className='popup'></div>
        )
}

The problem is inside render function the second state banks length is undefined.

How can I do multiple setstate inside componentDidMount.

Any help is highly appreciated.

Update: Resolved The mistake was

constructor(props) {
    super(props);
    this.state = {
        users: [],
        //MISSING BANKS array
    }
}
Prithviraj Mitra
  • 11,002
  • 13
  • 58
  • 99

1 Answers1

1

You should set state in a single update, updating both values at the same time. Otherwise you are instructing React to initiate two renders, the first would contain users value and an undefined value for banks (depending on your initial state declaration). This render would be quickly followed by a second pass, in which both state values users and banks would be defined.

The below example should work as required, in a single render.

Promise.all([
  axios.get(<url1>),
  axios.get(<url2>)
]).then(([res1, res2]) => {
  // call setState here
  const users = res1.data.users;
  const banks = res2.data.banks;
  this.setState({ users, banks });
});

On the other hand, if for some strange requirement you actually want two sequential renders you can use setState's done callback; example below.

this.setState({ users }, () => {
  this.setState({ banks });
});

This will ensure the first render is complete before requesting a new render via setState.

Jon Miles
  • 9,605
  • 11
  • 46
  • 66