The reason is that setState is more of a request for the state to change rather than an immediate change. React batches those setState calls for performance improvement. Calling setState() in React is asynchronous, for various reasons (mainly performance). Under the covers React will batch multiple calls to setState() into a single state mutation, and then re-render the component a single time, rather than re-rendering for every state change. Does this answer your question? Why does calling react setState method not mutate the state immediately? – ggorlen Jul 21 at 17:10
this.setState({
pencil: !this.state.pencil
}, myFunction)
You should invoke your second function as a callback to setState, as setState happens asynchronously. Something like:
this.setState({
pencil: !this.state.pencil
}, myFunction)
However in your case since you want that function called with a parameter you're going to have to get a bit more creative, and perhaps create your own function that calls the function in the props:
myFunction = () => {
this.props.updateItem(this.state)
}
React this.setState, and useState does not make changes directly to the state object. React this.setState, and React.useState create queues for React core to update the state object of a React component. Let’s dive into why this.setState and React.useStatedo not update immediately. Does it feel like when you call this.setState or React.useState, the changes feel like it’s a step behind?
If you’re using a class component, you will have to usethis.setState()
to update the state of a React component.
this.setState(state, callback);
The second parameter this.setState()
accepts is the callback function, and that’s where you’ll want to add your side effects.
This callback function will get triggered when React state has finished updating.
this.setState(newStateObject, () => {
// ... do some other actions
});
The example above uses the arrow function, but you can do it with a traditional function syntax.
this.setState(newStateObject, function() {
// ... do some other actions
});
That hook function will only activate if the values in the list change.
Let’s take a look at an example
let s;
const Foo = () => {
const [counter, setCounter] = React.useState(0);
// Emmulate componentDidMount lifecycle
React.useEffect(() => {
s = setInterval(() => {
setCounter(state => (state +1));
}, 1000);
}, []);
// This is for counter state variable
React.useEffect(() => {
if (counter > 9) {
clearInterval(s);
}
}, [counter]);
return <span>{counter}</span>;
};
State updates in React are asynchronous; when an update is requested, there is no guarantee that the updates will be made immediately. The updater functions enqueue changes to the component state, but React may delay the changes, updating several components in a single pass. The componentDidUpdate function is invoked immediately after a state update occurs. To avoid an infinite loop, you should always use a conditional statement to be sure that the previous state and the current state are not the same: Now that we’ve established that delaying reconciliation of updates requests in order to batch them is beneficial, there are also times when you need to wait on the updates to do something with the updated values. In the next section, we’ll see how to do that.
For example, consider the code below:
//React
const handleClick = () => {
setName("Amaka")
setAge(20)
setAddress("No 3 Rodeo drive")
}
The second parameter to setState()
is an optional callback function. This argument will be executed once setState()
is completed and the component is re-rendered. The callback function is guaranteed to run after the state update has been applied:
//React
handleSearch = (e) => {
this.setState({
searchTerm: e.target.value
}, () => {
// Do an API call with this.state.searchTerm
});
}
//React
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
// Do something here
}
}
The reason why the state doesn’t update immediately is because for each render, the state is immutable. Plenty of articles have been written about this saying setState is asynchronous. This may sounds probable but it isn’t the exact reason why your state doesn’t update immediately. …are both constants values ! So they’re immutable. The state remains constant inside the render but can be changed between two renders. The same goes for dispatch and useReducer. but this is actually normal, just as expected. The component has to rerender before updating the new state.
function onClick() {
//let's say last state was 1
setSomeState(2)
console.log(someState); //will log 1 but not 2
}
function App(){
const [count, setCount] = useState(1);
function onClick(){
setCount(count + 1)
console.log(count);
// First time the button is clicked this will log 1, not 2
// This console logged count will always "lag behind"
}
console.log(count)
//This will log 1 on first render
//before clicking the button.
//After the first button click, the state
//will be updated which triggers a second
//render and then this will log 2
return(
<button onClick={onClick}>increment count</button>
)
}
function onClick() {
await setCount(count + 1) //not possibile
console.log(count); //logs 2
}
//Instead of this:
function onChange() {
setCount(count + 1);
getData(count);
//here count is not equal to the state
//you just set, it's the previous state
}
//Do this:
function onChange() {
const newCount = count + 1;
setCount(newCount);
getData(newCount);
//now you can be sure you call getData
//with the state you just set
}
useEffect(() => {
getData(count);
}, [count])
To update the state of a component, you use the setState method. However it is easy to forget that the setState method is asynchronous, causing tricky to debug issues in your code. The setState function also does not return a Promise. Using async/await or anything similar will not work. Use the useEffect hook to wait for state to update in React. You can add the state variables you want to track to the hook’s dependencies array and the function you pass to useEffect will run every time the state variables change.30-Apr-2022 When you directly update the state, it does not change this. state immediately. Instead, it creates a pending state transition, and accessing it after calling this method will only return the present value. You will lose control of the state across all components.
In this session, we’ll try our hand at solving the React State Not Updating Immediately puzzle by using the computer language. The code that is displayed below illustrates this point.
//In case of hooks, you should use useEffect hook.
const [fruit, setFruit] = useState('');
setFruit('Apple');
useEffect(() => {
console.log('Fruit', fruit);
}, [fruit])
One can solve the same problem using a variety of different strategies React State Not Updating Immediately. There is no one right way to do it. In the paragraphs that follow, we will discuss the many different alternatives to the current problem.
myFunction = () => {
this.props.updateItem(this.state)
}
Many examples helped us understand how to fix the Setstate Not Updating State Immediately error. Hello everyone, in this post we will look at how to solve the Setstate Not Updating State Immediately problem in the programming language. Setstate Not Updating State Immediately With Code Examples React Native Load Function Each Time Visit Screen With Code Examples
//In case of hooks, you should use useEffect hook.
const [fruit, setFruit] = useState('');
setFruit('Apple');
useEffect(() => {
console.log('Fruit', fruit);
}, [fruit])
Using a different strategy, which is described below with code samples, the identical issue Setstate Not Updating State Immediately can be resolved.
myFunction = () => {
this.props.updateItem(this.state)
}
When I do an onclick event. I have search a while ago that I need to bind the onclick function in constructor but still the state is not updating. \ The method setState() takes a callback. And this is where we get updated state. So When callback fires, this.state is the updated state. You can get mutated/updated data in callback. nodemon app crashed - waiting for file changes before starting May 13
Here's my code:
import React from 'react';
import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
import BoardAddModal from 'components/board/BoardAddModal.jsx';
import style from 'styles/boarditem.css';
class BoardAdd extends React.Component {
constructor(props){
super(props);
this.state = {
boardAddModalShow: false
}
this.openAddBoardModal = this.openAddBoardModal.bind(this);
}
openAddBoardModal(){
this.setState({ boardAddModalShow: true });
// After setting a new state it still return a false value
console.log(this.state.boardAddModalShow);
}
render() {
return (
<Col lg={3}>
<a href="javascript:;" className={style.boardItemAdd} onClick={this.openAddBoardModal}>
<div className={[style.boardItemContainer,style.boardItemGray].join(' ')}>
Create New Board
</div>
Consider this example.
this.setState({
name: "Mustkeom"
},
() => { //callback
console.log(this.state.name) // Mustkeom
}
);