Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
922 views
in Technique[技术] by (71.8m points)

javascript - react select onChange returning previous value instead of current

I'm attempting to update the state of a parent component after a user changes the value of a child components select element.

While I've got it somewhat working, I've noticed that when I fire the onChange event on my select element it'll return the previous value instead of the one that has just been selected.

My React Code

class Parent extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            data: {
                condition: "any"
            }
        };
    }

    update = data => {
        this.setState({ data: { ...this.state.data, ...data } });
        // this gets called every time i change the value of my select
        console.log(this.state.data);
    }

    render(){
        return (
            <div className="parent">
                <Child
                    condition={ this.state.data.condition } 
                    onUpdate={ data => this.update(data) } />
            </div>
        );
    }
}

class Child extends React.Component{
    updateParent = data => {
        this.props.onUpdate(data);
    }

    condition = props => {
        const options = [["any", "Any Condition"], ["new", "Brand New"], ["used", "Used"]];
        return (
            <select 
                defaultValue={ props.selected } 
                // if i select 'used', the console will return 'any', 
                // then if i select 'new', the console will return 'used'
                onChange={({ target }) => this.updateParent({ condition: target.value })}>
                {
                    options.map(([id, name]) => <option key={id} value={id}>{name}</option>)
                }
            </select>
        );
    }

    render(){
        return (
            <div className="child">
                <this.condition selected={ this.props.condition } />
            </div>
        );
    }
}

I've tried searching around, but I couldn't find any solutions to my problem (at least none that I could understand with my limited understanding). Apologies if it's glaringly obvious, but I've only just started learning React and JSX.

Cheers

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

setState operations are async in nature. So whenever a setState op is done, its not guaranteed that the updated value of state will be available just after the setState statement

From React Doc

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

Now, if you want to use the new state value, you should store the value, in this case the data, in a variable, set your state, but use the variable to perform other operation inside the function, like calling API,etc.

Edit (As pointed out by @Grover):

setState also provides a second argument which is a callback that gets fired after the update operation takes place. One can get the updated state value in it and can use this to perform operations with the updated values.

this.setState({foo: 'bar'}, () => { 
    // actions
});

However, the React Doc suggests using componentDidUpdate instead of setState callback. This answer tries to explain it why: What is the advantage of using componentDidUpdate over the setState callback?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...