Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update and use state by event handler in React

Tags:

reactjs

I have component Searcher with function SearchArticle() which is correctly using this.state.search with DEFAULT value after component mounts (console displaying Searching...:DEFAULT) . But when I update this.state.search with handleKeyPress(e) them same function SearchArticle() is using prev state before it updates to e.target value (console displaying Searching...:DEFAULT again). Not sure how to fix it.

class Searcher extends Component {

    constructor(props) {
        super(props);
        this.state = { 
            article: [], search: "DEFAULT"
        }; 
    }  

    searchArticle() { 
        console.log('Searching...: ', this.state.search)                                 
    }

    handleKeyPress = (e) => {
        if (e.key === 'Enter') {                            
            this.setState({search: e.target.value});
            this.searchArticle();
        }
    }

    componentDidMount() {
        this.searchArticle();     
    } 

    render() {
        return (
            <div className="row">
            Search: <input onKeyPress={this.handleKeyPress} type="text" />
            </div>            
        )
    }

}
like image 776
irom Avatar asked Sep 18 '25 19:09

irom


1 Answers

Most likely the state hasn't updated by the time the console.log is executed. This is because setState() is asynchronous.

So try this instead:

handleKeyPress = (e) => {
  if (e.key === 'Enter') {                            
    this.setState({search: e.target.value}, () => {
       this.searchArticle();
    });       
  }
}

I moved your searchArticle() into the setState() callback. This will guarantee its execution after the state has actually updated.


Read more about setState() here.

Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied.

[...]

The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered.

like image 56
Chris Avatar answered Sep 21 '25 14:09

Chris