score:5
why it looks like it doesn't work?
there are a couple hints that can help understand what's going on.
count
is const
, so it'll never change in its scope. it's confusing because it looks like it's changing when calling setcount
, but it never changes, the component is just called again and a new count
variable is created.
when count
is used in a callback, the closure captures the variable and count
stays available even though the component function is finished executing. again, it's confusing with useeffect
because it looks like the callbacks are created each render cycle, capturing the latest count
value, but that's not what's happening.
for clarity, let's add a suffix to variables each time they're created and see what's happening.
at mount time
function counter() {
const [count_0, setcount_0] = usestate(0);
useeffect(
// this is defined and will be called after the component is mounted.
() => {
const id_0 = setinterval(() => {
setcount_0(count_0 + 1);
}, 1000);
return () => clearinterval(id_0);
},
[]);
return <h1>{count_0}</h1>;
}
after one second
function counter() {
const [count_1, setcount_1] = usestate(0);
useeffect(
// completely ignored by useeffect since it's a mount
// effect, not an update.
() => {
const id_0 = setinterval(() => {
// setinterval still has the old callback in
// memory, so it's like it was still using
// count_0 even though we've created new variables and callbacks.
setcount_0(count_0 + 1);
}, 1000);
return () => clearinterval(id_0);
},
[]);
return <h1>{count_0}</h1>;
}
why does it work with let c
?
let
makes it possible to reassign to c
, which means that when it is captured by our useeffect
and setinterval
closures, it can still be used as if it existed, but it is still the first one defined.
at mount time
function counter() {
const [count_0, setcount_0] = usestate(0);
let c_0 = count_0;
// c_0 is captured once here
useeffect(
// defined each render, only the first callback
// defined is kept and called once.
() => {
const id_0 = setinterval(
// defined once, called each second.
() => setcount_0(c_0++),
1000
);
return () => clearinterval(id_0);
},
[]
);
return <h1>{count_0}</h1>;
}
after one second
function counter() {
const [count_1, setcount_1] = usestate(0);
let c_1 = count_1;
// even if c_1 was used in the new callback passed
// to useeffect, the whole callback is ignored.
useeffect(
// defined again, but ignored completely by useeffect.
// in memory, this is the callback that useeffect has:
() => {
const id_0 = setinterval(
// in memory, c_0 is still used and reassign a new value.
() => setcount_0(c_0++),
1000
);
return () => clearinterval(id_0);
},
[]
);
return <h1>{count_1}</h1>;
}
best practice with hooks
since it's easy to get confused with all the callbacks and timing, and to avoid any unexpected side-effects, it's best to use the functional updater state setter argument.
// ❌ avoid using the captured count.
setcount(count + 1)
// ✅ use the latest state with the updater function.
setcount(currcount => currcount + 1)
in the code:
function counter() {
const [count, setcount] = usestate(0);
useeffect(() => {
// i chose a different name to make it clear that we're
// not using the `count` variable.
const id = setinterval(() => setcount(currcount => currcount + 1), 1000);
return () => clearinterval(id);
}, []);
return <h1>{count}</h1>;
}
there's a lot more going on, and a lot more explanation of the language needed to best explain exactly how it works and why it works like this, though i kept it focused on your examples to keep it simple.
Source: stackoverflow.com
Related Query
- React useState does not update value
- React useState hook does not update the lonlat value in OSM
- React useState does not seem to accept a default value here?
- PrevState does not update state value immediately in React JS
- React Hooks: updating state using useState does not update the state immediately
- In React useEffect does not update after the value has changed from other component
- React setState does not update a state array value
- useState React Hook set method does not update state immediately in onChange()
- The value of textbox does not update in React
- How to re-render the component in react if useState does not change or hold the last value
- React js useState array does not update
- useState does not update the value on Component Re-render
- React - setState does not update the value
- react does not update localstorage value based on state
- Unable to update a list with react when its value is being changed using the hook useState function from React TypeError: map is not a function
- React useState does update in dev tools but not in the console
- React useState in context does not update
- React useImerativeHandle does not update value
- React Drop Down does not update value when chosen
- React router 4 does not update view on link, but does on refresh
- React - useState not setting initial value
- React - useState - why setTimeout function does not have latest state value?
- React Checkbox Does Not Update
- React + Redux: Component does not update
- React does not refresh after an update on the state (an array of objects)
- useState in useEffect does not update state
- React component view does not get update
- React - setting input value with JavaScript does not trigger 'onChange'
- React js changing state does not update component
- My React component does not update in the Safari browser
More Query from same tag
- Set text on the same y-aligment line
- React- hover effect to hide div doesn't work
- Cannot read property name of null reactjs
- Is there access to Formik props inside <Field validate>
- React redux, array state not updating
- Handling an indetermined amount of states for n checkboxes in React
- How could I control amplify DataStore sync
- Should I use React hooks when starting new project?
- How to make the background color of an app cover the entire screen (using style) in React Native?
- How to send pass an object as a parameter to a post request
- How to import ipcRenderer in react?
- React loop with nested props
- Conditional link in JSX
- React useState hooks initial value is null, after few seconds when got value then not updating where is use the value
- How to prevent rerenders with react-router-dom and react-redux when changing route?
- React render when props change
- Why is updateQueryData from RTK query not updating my state?
- Javascript Vue or React storing sensitive information client side safety
- React.js start a new line after every number
- .map() method using prior state in React
- block statement surrounding arrow body error with map
- Radium error - Unknown plugin "flow-comments"
- ReactJs make a separate file for fetch
- Is there a way to render .jsx components inside express server
- passing onclick function as argument to another component in react/typescript
- React-router import routes
- Prevent React-Select from ever being blank
- React : onMouseEnter / onMouseLeave not working with state
- convert Epoch to js date object/moment date object in react js excluding timezone
- Why side effect is not ok in React