score:0
that is how closures work in js. the functions passed to settimeout will get the issubmitting
variable from the initial render, since issubmitting
is not mutated.
you can get a function as an argument instead of prop to setissubmitting
that means that issubmitting
is gonna be updated value.
settimeout(() => {
setissubmitting(issubmitting => !issubmitting);
}, 1500);
hope it will work
score:0
maybe little overkill byt you can handle this by using promise
const handlerequest = () => new promise((resolve, reject) => {
settimeout(() => {
createprofile(formdata, history, edit)
.then(response => resolve(response))
.catch(error => reject(error));
}, 1500);
}
const onsubmit = (event) => {
event.preventdefault();
setissubmitting(true);
handlerequest().finally(() => setissubmitting(false);
};
and maybe second overkill: i'm not sure why you need to submit data after 1.5s, not immediately but you can have both 1.5s loader and request sended just after submit by creating some dummy promise
and using promise.all
like this:
const dummypromise = () => new promise((resolve, reject) => {
settimeout(() => resolve(), 1500);
}
const onsubmit = (event) => {
event.preventdefault();
setissubmitting(true);
promise.all([
dummmypromise(),
createprofile(formdata, history, edit)
])
.then(response => ...handle successfull response)
.catch(error => ...handle request error)
.finally(() => setissubmitting(false));
};
the thing is you don't know how long your request will last so by setup like this you are prepared for different situations: sumbmit request is sent immidately and promise.all
will resolve after all promises resolves so if your request resolves very fast you will still have 1.5s loader, on the other hand if request will last longer than 1.5s you will still have active loader indicating that request is not finished yet. like i said overkill in your situation but i hope my comment will contain some nice inspirations how to improve handling async requests ;)
score:0
issubmitting
isfalse
by default, and upon submitting, i turn it totrue
, after that i set a timeout to set it back tofalse
. but somehow, it does not get set back tofalse
see commented code
that is how closures work
but how come in plain js, i dont have this problem? sounds like it has to do with usestate?
yes, in plain js you have the same problem. i'll show you:
let storedvalue = false;
function setstoredvalue(newvalue) {
storedvalue = newvalue
}
// usestate() is basically this; more or less.
// the place where `storedvalue` and `setstoredvalue` are kept is differrent,
// but that's not relevant to the issue at hand.
function gimmethevalueandasetter() {
return [
storedvalue,
setstoredvalue
]
}
function element(label) {
// you create a local **constant** copy of the state at this moment
const [localvalue, setstoredvalue] = gimmethevalueandasetter();
// and all your logs here are based off of this local **constant**!
console.log(label, "#1 local:", localvalue, " stored:", storedvalue);
setstoredvalue(!localvalue);
console.log(label, "#2 local:", localvalue, " stored:", storedvalue);
settimeout(() => {
console.log(label, "#3 local:", localvalue, " stored:", storedvalue);
setstoredvalue(!localvalue);
console.log(label, "#4 local:", localvalue, " stored:", storedvalue);
}, 100);
}
// render element
element("first render");
console.log("after first render:", storedvalue);
element("second render");
.as-console-wrapper{top:0;max-height:100%!important}
back to your code. instead of flipping the state, better set the explicit value. this is also simpler to reason about:
const onsubmit = (e) => {
e.preventdefault();
// we don't want to submit while another submit is still in progress
// right?
if(issubmitting) return;
setissubmitting(true);
settimeout(() => {
createprofile(formdata, history, edit);
setissubmitting(false);
}, 1500);
};
ain't this simpler to reason about than what you had before? issubmitting
was false
then i've flipped it to true
, so now i have to flip it again to get back to false
, ...
score:1
the state update using the updater provided by usestate hook is asynchronous, and will not immediately reflect the updated changes.
i.e
console.log(issubmitting); // false
setissubmitting(!issubmitting);
console.log(issubmitting); // false
instead you should useeffect,
const onsubmit = (e) => {
e.preventdefault();
setissubmitting(!issubmitting);
};
useeffect(() => {
// action on update of issubmitting
if(issubmitting) {
settimeout(() => {
createprofile(formdata, history, edit);
setissubmitting(!issubmitting);
}, 1500);
}
}, [issubmitting]);
Source: stackoverflow.com
Related Query
- setState within setTimeout returns confusing results
- How do I setState within React's recompose's lifecycle method?
- Is it OK to call setState from within shouldComponentUpdate?
- JS unit testing using enzyme: how to wait for setState within component's method to finish before proceeding with test case
- setTimeout in react setState
- react hooks setTimeout after setState
- setState method causes infinite loop of Results in Reactjs Functions
- setState of an object within an array
- Accessing Passport's req.user within React (ES6)? API call returns req.user as undefined
- Reducer that returns a collection of reducer results
- get latest state value after setState hook within async await block in react
- Why setState in setTimeout not batching?
- Using setTimeout in setState callbacks
- Test of reducer returns the results which are not equal to expected
- Reactjs: setState always fails and returns undefined in componentDidMount
- React's SetState within Firebase Auth's onAuthStateChanged causing setState to be undefined
- Using setState to change multiple values within an array of objects -- ReactJS
- react-table, useState hook within table results to default value although set before
- Webpack crashes in console: setState takes an object of state variables to update or a function which returns an object of state variables
- How to execute a function AFTER an API-Call was made with setState within useEffect?
- React setTimeout and setState inside useEffect
- How to setState from within a mapped item within React component
- React: Display loader whilst background image is loading results in setState error
- Calling setstate after processing forEach within useEffect
- Why custom hook returns results twice
- spread operator not working in nested setState within useEffect using .map() function
- Returning styling via settimeout within styled-components declaration
- Updating mobx store observable within self results in 'Cannot read property of <observable> of undefined'
- setState in React results in Uncaught ReferenceError
- I tried to set my state, but it returns "Can't call setState on a component that is not yet mounted." error
More Query from same tag
- React onClick not propagating event
- React: Functional component render two times the same Div
- How do I connect to a websocket it react instead of plain javascript?
- Pass multiple functions as a single prop using react hooks
- Animation in react-dnd
- Calling Parent Function in Child Component in React
- No unused expressions on function inside componentDidMount
- Why is my component not re-rendering after updating it?
- State depending on other state not updating when child changes
- Is it possible to wait for all actions in the ofType operator to be called before calling next?
- TypeScript / React: Setting value of input to event.target.nodeValue
- How do I refresh a component's select items when the items are changed in another component?
- React form error: Form submission canceled because the form is not connected
- Type Error: cannot read property ' map ' of undefined
- List in React component not updating when item is removed from array
- Overlaying or adding a view on top of another : React Native
- reactjs not translating object and html
- Reactjs submit multiple forms
- React: Render different component if authenticated at root
- Check if Logged in - React Router App ES6
- Use string "array[n]" as variable
- I can't access the redux store properly in react components
- Positioning CSS
- Accessing express server from different geo location
- React Hooks - set last value?
- How to perform action after all parallel queries are successful in "React-Query"
- Material UI v1.0.0 how to override Stepper classes to set icon size
- active classes for menu items , its should not active all list
- React Native - Displaying a Loading Screen Component in a Javascript Promise
- window.addEventListener('load',... not firing on Safari?