How to clear the existing data in react state variable (Array) and assign another array to it. I have try below thing but it doesn't works.
itemsChanged(items) {
this.setState({item : []}) //item is my state variable
this.setState({item : items})
console.log("ITEMS : ",this.state.item) //this will not print the updated value
}
Thanks in advance
You don't need to assign an empty array first. Just pass the new array to it. The only reason why it's not working is that setState is an asynchronous call. Use it like this
this.setState({item : items}, () => console.log("ITEMS : ",this.state.item) )
According to React's docs
React may batch multiple setState() calls into a single update for performance.
If you want to check your state value after setState, you should do like:
this.setState({item : items}, () => console.log(this.state.item));
setState is an async method. So, when you print it on console, It still can be updating. You can use console log before return render.
...
render(){
console.log("ITEMS : ",this.state.item);
return (<div>...</div>)
}
...
As they describe:
setState(updater, [callback])
so that may suggest it is not a synchronous operation.
Use:
itemsChanged(items) {
var me = this;
me.setState({item : items}, function(){
console.log("ITEMS : ", me.state.item);
});
}
One thing you should understand about setState is that it works asynchronously. If you try to console.log the state directly after calling setState, you won't see any changes yet.
You also don't have to clear out the array by calling setState with an empty array--you can just replace the current array with the new array.
this.setState({ items: newItems });
If you want to log the change, I'd suggest trying to do it in the component's componentShouldUpdate method.
setState is an async function,if you are writting the code as that:
this.setState({xxState})
console.log(this.state.xxState)
The program will execute the console.log first,so you should write as that:
this.setState({xxx},()=> {
console.log(this.state.....)
})
And it will be work well.
Related
I got array with objects from API and then I use:
componentDidMount(){
this.props.getAllPosts()
this.props.getAllComments()
}
Then I put data to my Redux but when I want to change this array (for instance add new object), I need to refresh the page, because it doesn't work asynchronous...
So I solved to use ComponentDidUpdate but it renders every second hundreds times, What i need to do?
You might need to wrap the setState call in an if block, as the docs describe here
Any call to setState inside of ComponentDidUpdate, will cause ComponentDidUpdate to be called again.
You need to compare is there any difference between the old props(state) and the new(updated) props(state) or the code may exec in dead loop. Just like the following snippet:
componentDidUpdate(prevProps, _prevState) {
const { activeKey: prevActiveKey } = prevProps
const { activeKey } = this.props
if (prevActiveKey !== activeKey && !!activeKey) {
this.getTemplateList()
}
}
I know mutating state can work against PureComponent (or similar)
Is there other reason not to mutate state?
I wonder if the 3rd way is ok to do?
// The Right Way:
// copy the existing items and add a new one
addItemImmutably = () => {
this.setState({
items: [...this.state.items, this.makeItem()]
});
};
// The Wrong Way:
// mutate items and set it back
addItemMutably = () => {
this.state.items.push(this.makeItem());
this.setState({ items: this.state.items });
};
// is this ok? (mutate but set state with new copy)
addItem3rdWay = () => {
this.state.items.push(this.makeItem());
this.setState({items: [...this.state.items]});
}
Here is an example: You have fired an async method that sends a request with your current state data. In meantime you have executed a function that mutates the state. This will cause the async function to send the mutated state despite the fact it intended to send the state before mutation.
You can think state as your database.
You don't directly mutate your database, you modify your database by API.
setState is the API.
Of course, you can directly mutate your database, but other components will have a hard time retrieving those data, because those are inconsistent right now, because somebody doesn't use the API that framework provides for you.
If you really like the way mutating state, you can use Vue, Vue is designed like that.
I tried to run the code below, but I got an undefined from the console.log statement. Any thoughts?
this.setState({ [show]: true })
console.log("this.state.show: " , this.state.show);
In your code you don't set state exactly for show.
Example:
const show = 'light';
this.setState({[show]: false}) // you set state for 'light'(this.state.light: false)
If you don't set variable show before, you should use:
this.setState({ show: true })
And if you need to get state right after setting:
this.setState({ show: true }, () => console.log("this.state.show: " , this.state.show);)
If you are trying to check if state did update the best way to do that is simply to check for it inside the render() function, because the component is always re-rendered when you update the state. This would probably look like this (I have added a ternary operation as an example of how you can show and hide your component):
render(){
console.log(this.state.show);
return this.state.show ? <MyComponent /> : null;
}
But if you really want to check if the state changed just after using the setState function, for example inside another function (and not render()), you will need to call console.log inside a callback. This is because state takes some time to update and therefore synchronous code would fail. setState takes callback functions as a second parameter. So, you can just re-write like this:
this.setState({ show: true }, () => console.log("this.state.show: " , this.state.show));
Hope that helped...
I think it might be silly question to ask but trust me I am stuck to find an answer . Actually , I am trying to access updated state value in class function above render function but I am not getting updated value . when I console value in render function I got updated value . Could someone please help me how to access updated value .
Thanks
Code
fetchAgents = e => {
this.setState({
value: e.target.value
});
};
fetchFilteredInventories = e => {
axios
.get(`/api/reports/agents/?branch=${this.state.value}`)
.then(response => {
this.setState({
agents: response.data
});
});
};
when I try to access updated state value in fetchFilteredInventories I am getting null value . Could someone help me to achieve my goal
setState is asynchronous. When you console.log after setState, the state is not changed yet, it is in the process of changing. Try this
this.setState({
value : e.target.value
},()=>console.log(value));
You will see the value is updated. setState allows a callback function as arguement. So use the callback function to use the updated state value.
Read the docs for further info: https://reactjs.org/docs/state-and-lifecycle.html#using-state-correctly
It depends on where you are calling your fetchFilteredInventories function.
After a state update in a React component certain lifecycle hooks get called, such as componentWillUpdate, componentDidUpdate. you can read about them in React docs here State and Lifecycle.Make sure you are calling your API call function at the right moment.If you can, put your whole component code here for better answers.
Try This
axios.get(`/api/reports/agents/?branch=${this.state.value}`).then(function(response) {
this.setState({
agents: response.data
});
}.bind(this));
I'm having an issue when mixing useState and the useEffect hook. I can't seem to reference the new query state in onReady().
function Foo() {
const [ query, setQuery ] = React.useState('initial query');
React.useEffect(() => {
myLibClient.onReady(onReady)
}, []);
function onReady() {
const newQuery = myLibClient.createQuery({ options });
setQuery(newQuery);
console.log(query); // initial query :(
}
return null;
}
Can anyone see what I'm doing wrong or explain why this doesn't work?
The issue here is that like this.setState in the class-based react components, the setQuery function also sets the state asynchronously.
See Reference react docs and RFC: Why it is asynchronous?
So if you try to access the value just after setting the state, you'll get the older value.
You can verify this behavior here. https://codesandbox.io/s/2w4mp4x3ry. (See the file named Counter.js)
You'll see that before and after values for counter are same.
If you want to access the updated value, you can access it in the next render cycle. I have created another example where you can see that new query value is being rendered.
https://codesandbox.io/s/8l7mqkx8wl (See the file named Counter.js)