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));
Related
Alright so I am building this CRUD app with a React driven U/I. I'm having an issue with my state updating. Below are the code snippets that are involved in the problem. I've tried figuring it out myself and think it's that my state is updating correctly but it gets sent to the server before the state can be updated and when my component remounts it gets the old state from the server and overwrites the new one. The server always gets a state that is n - 1 to the actual number of items. Also if you know any ways that i could improve, please let me know I feel like this is a lot of work to do just 3 tasks!
Thank you in advance.
My state
this.state = {
newItem:{},
todos:[]
}
The retrieval methods
componentDidMount(){
this.getTodos(this.props);
}
getTodos(props){
axios.get(process.env.REACT_APP_SERVER+`/${props.match.params.id}/todos`)
.then(
(res)=>{
this.setState({todos:[...res.data]});
}
)
}
My creation and update methods
handleOnChange(e){
this.setState({newItem:{title:e.target.value, complete:false}});
}
addNewItem(){
this.setState({todos:[...this.state.todos, this.state.newItem]});
this.updateTodoList(this.props);
}
updateTodoList(props){
axios.put(process.env.REACT_APP_SERVER+`/${props.match.params.id}/todo/add`, this.state.todos).then(res=>{
console.log(res.data);
});
}
Update: Oh snap! That is what I figured, you've fixed my bug!
The problem is you're calling updateTodoList before the state is already updated.
Do this:
addNewItem(){
this.setState({todos:[...this.state.todos, this.state.newItem]}, () => {
this.updateTodoList(this.props);
});
}
setState has a callback that is invoked after state is already updated so is the place you can be sure it is, and call next fn.
The state update is an asynchronous process.
The issue here is your update API call is happening before the state
update.
To fix this issue use this syntax for state update.
addNewItem () {
this.setState (
{todos:[...this.state.todos, this.state.newItem]},
() => {
this.updateTodoList(this.props);
}
);
}
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'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)
This question already has answers here:
Why does calling react setState method not mutate the state immediately?
(9 answers)
Closed 5 years ago.
onSelectedRow(user, clickEvent){
const state = this.state;
this.state['userId'] = clickEvent.target.getAttribute(user['mta:UserId']);
this.setState(state);
console.log(user['mta:UserId']);
console.log(this.state);
}
Okay, so when I click a table-cell in my app this function gets called.
The point of it is to take the users UserId and set the state. This UserId is later on passed down to a child component and used to get specific information. The problem is that I get the correct data in the first console.log but when I then log this.
state the userId is still null for some reason. Anyone had similiar problems?
It's most probably because you're not updating the const state, but instead trying to mutate the state itself.
Also, you don't have to make a copy of a state. You can update just the field you want to update like this:
onSelectedRow(user, clickEvent) {
this.setState({
userId: clickEvent.target.getAttribute(user['mta:UserId'])
}, () => { console.log(this.state.userId) });
console.log(user['mta:UserId']);
}
Also, your console.log won't read immediate change in the state as setState is an async action.
If you really want to read it you can pass the callback to the setState which fill fire right after the state is updated, or use React's lifecycle method componentDidUpdate().
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.