robmax
robmax

Reputation: 352

React: wait for state update

On my page I have two <select> elements. The second one depends on the first. The first one contains building numbers, the second rooms in that building. When I'm changing building I want to change rooms also, but state still has the old building state. For example in first select I have buildings [A, B, C]. At the beginning first select is set on A and rooms in the second select are correct, but after change building to B, room are still for A, then changing building to C, rooms are for B.

Part of the jsx code:

<div className="row">
    <div className="col">
       <label> Budynek: </label>
    </div>
    <Building onChangeHandler={event => this.onChangeHandler(event)} />
</div>
<br />
<div className="row">
   <div className="col">
       <label> Sala: </label>
   </div>
   <Room building={this.state.building} />
</div>


Method for changing state after select another value from <select>

onChangeHandler(event) {
    this.setState({ building: event.target.value }, () => {});
}

I know that setState() doesn't update state immediately. But how to wait until it will be update?
<Room/> component is updating on componentWillReceiveProps()


update

fetchRooms() {
    fetch(`http://localhost:3000/rooms/building/${this.props.building}`)
        .then((res) => {
            return res.json()
        })
        .then(data => {
            let rooms = '';
            data.forEach(room => {
                rooms += `
                    <option value="${room.number}">${room.number}</option>
                `
            })
            this.setState({ rooms });
        })
}

componentDidMount() {
    this.fetchRooms();
}

componentWillReceiveProps(){
    this.fetchRooms();
}

Upvotes: 0

Views: 7612

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281626

In componentWillReceiveProps you are calling this.fetchRooms, however in fetchRooms function you still use this.props and hence a new data is not retrieved. Also you must do a comparison before calling a function

fetchRooms(props) {
    const { building } = props || this.props;
    fetch(`http://localhost:3000/rooms/building/${building}`)
        .then((res) => {
            return res.json()
        })
        .then(data => {
            let rooms = '';
            data.forEach(room => {
                rooms += `
                    <option value="${room.number}">${room.number}</option>
                `
            })
            this.setState({ rooms });
        })
}

componentDidMount() {
    this.fetchRooms();
}

componentWillReceiveProps(nextProps){
    if(nextProps.building !== this.props.building) {
       this.fetchRooms(nextProps);
    }
}

Upvotes: 3

Ishwor Timilsina
Ishwor Timilsina

Reputation: 1464

If all the props that your component receives are from this component, then all you need to do is make sure this component does not update unless you want it to. You can use shouldComponentUpdate for this.

Something like this. (I haven't tested this, just a thought that I think could work.)

constructor(props){
    super(props)
    this.state = { 
        shouldUpdate: false
    }
}

onChangeHandler(event) {
    this.setState({ building: event.target.value }, () => {
        shouldUpdate: true
    });
}

shouldComponentUpdate(nextProps, nextState){
    if(nextState.shouldUpdate){
        return true;
    }
    return false;
}

render() {
    ....
}

Upvotes: 0

Related Questions