React.js, wait for setState to finish before triggering a function?
setState()
has an optional callback parameter that you can use for this. You only need to change your code slightly, to this:
// Form Input
this.setState(
{
originId: input.originId,
destinationId: input.destinationId,
radius: input.radius,
search: input.search
},
this.findRoutes // here is where you put the callback
);
Notice the call to findRoutes
is now inside the setState()
call,
as the second parameter.
Without ()
because you are passing the function.
React waiting for setState to finish then call a function
Fixed using the inbuilt React Context, passing the calculator the values as props and wrapping all the componenents needing the data with a value provider.
How to wait for setState in useEffect until render?
In generic, it would set a state isFetched
to determine if the data from api is ready or not. And when the isFetched
equal to true
, it means the item.tags
have value.
const [isFetched, setIsFetched] = useState(false);
useEffect(async () => {
await axios.all(...).then(() => {
...
...
setIsFetched(true);
})
}, [])
// You could return null or an Loader component meaning the api is not ready
if (!isFetched) return null;
return (
<div>
{item.tags.map((tag, index) => {
return <Chip label={tag} key={index} />
})}
</div>
)
On the other hand, you could use optional chaining to avoid using map
from an undefined
value (that is item.tags
), the right way is replace item.tags.map
to item.tags?.map
.
React hooks - wait until the state has been updated
You can use the useEffect
hook:
useEffect(() => {
//your code
}, [data]);
That will trigger what is inside every time data
changes.
How can I wait until the functions finish in Reactjs?
I think the issue here is self.getDividend();
and self.getDivisor();
are async operations. They will take some time to complete. By the time you hit the next line const { dividendList , divisorList} = self.state;
, these operations are not complete and you will end up getting empty lists.
One way to address this is using moving your doCal function logic after getDividend and getDivisor are completed. You can also execute these in parallel instead of in a sequence. I used async format instead of .then(). It is just a sysntatic sugar. You can achieve the same using .then() if you prefer that way
async function doCalc() {
const prom1 = axios.get('https://..dividentList');
const prom2 = axios.get('https://..divisorList');
const results = await Promise.all([ prom1, prom2]); // wait for both promise to complete
// look inside results to get your data and set the state
// continue doCal logic
}
Using .then()
request1('/dividentList')
.then((res) => {
//setState for divident
return request2('/divisorList'); // this will return a promise to chain on
})
.then((res) => {
setState for divisor
return Promise.resolve('Success') // we send back a resolved promise to continue chaining
})
.then(() => {
doCalc logic
})
.catch((err) => {
console.log('something went wrong');
});
Wait for setState to finish and then return data
The reference of markedDates
value still the same, because you're just adding a value to its current value and it don't change its reference.
To make react knows thats value changed the value of component props should have a new reference in memory.
So when you need a new state based on previous state you should use the previous state as parameter in a function inside this.setState like ReactJS docs says...
onDayPress = (day) => {
if (this.state.isStartDatePicked == false) {
this.setState(prevState => ({
markedDates: {
[day.dateString]: {
startingDay: true,
color: '#00B0BF',
textColor: '#FFFFFF'
}
},
isStartDatePicked: true,
isEndDatePicked: false,
startDate: day.dateString,
}));
} else {
let startDate = moment(this.state.startDate);
let endDate = moment(day.dateString);
let range = endDate.diff(startDate, 'days')
this.setState(prevState => ({
markedDates: {
...prevState.markedDates,
[day.dateString]: {
endingDay: true,
color: '#00B0BF',
textColor: '#FFFFFF'
},
},
isStartDatePicked: false,
isEndDatePicked: true,
startDate: ''
}), this.checktest);
}
}
Related Topics
Getting Null Value in List When Passing by Ajax Call to MVC Controller
How to Remove Errors Warnings from Console
Allowing/Replacing Comma as Number Separator for Input Type="Number" Using Rails
How to Simulate Key Press Events Programmatically
How to Automatic Click a Button on a Webpage
Fetch() Unexpected End of Input
How to Add Node Module to Angular Project If Is Not Schematics Enabled
How to Cancel Ongoing Http Requests When There's a New Requests in Angular 6 With Rxjs 6
Jquery: Simplest Way to Check Url for a Parameter and Pass It to Anchor Href If It Exists
Multiple Key Names, Same Pair Value
How to Display an Image from an Array of Images in React
How to Disable Onclick Without Altering Its Function
React-Native: Convert Image Url to Base64 String
How to Store Data After Refreshing the Web Page
Is There a Function in Lodash to Replace Matched Item