function App() {
const [count, setCount] = useState(0);
function increase() {
setCount(count 1);
console.log(count);
}
return (
<div>
<h1>{count}</h1>
<button onClick={increase}> </button>
</div>
);
}
When I console.log the value of count, it increases by 1 even though I have declared it using const. How is it still being updated? I have a feeling it's related to the useState function, but I'm not sure.
Another thing is, if we can update using count 1
, why can't we do so using count
?
Thanks a lot for the guidance!
Code is here: https://codesandbox.io/s/g8dgv0?file=/src/components/App.jsx
CodePudding user response:
The '0' value in your useState(0)
is the default/initial value that the state will start with. From there you can modify it using setCount(value)
For your second question, from howtojs.io:
In React, we should not modify the state variables directly. We need to pass the new data to the state variable modifier functions (such as setCount), then React will modify the value of the state variable.
One more thing we need to remember is, when we do count in JavaScript, the variable will be incremented after consuming the variable first.
So, when we do setState(count ), first the value of count will be passed to the setState function, then the value of count will be incremented inside the function component (this is not recommended way).
CodePudding user response:
React is fundamentally a rendering library, and the paradigm it uses is that the info that's rendered on the screen should flow directly from the current state stored in React. So, calling a state setter does two things:
- It updates the internal state React has for that state value
- It tells the component to re-render, so as to generate a new view based on the new updated state
Whenever a functional component re-renders, the function runs again - and useState
can return different values depending on what the current value of the internal state is.
For a similar example in vanilla JS:
let internalValue = false;
const getValue = () => internalValue;
const setValue = (newValue) => {
internalValue = newValue;
setTimeout(App);
};
const App = () => {
const stateValue = getValue();
if (!stateValue) {
setValue(true);
}
console.log('app rendered with stateValue of', stateValue);
};
App();
Above, you can do const stateValue = getValue();
and get different values for stateValue
depending on other factors - because the App
function ran again.
Another thing is, if we can update using count 1, why can't we do so using count ?
Because, as explained in the beginning of the answer, the view should flow from the state in React, and when updating the state, you need to tell React to re-render; reassigning a variable, by itself, doesn't have side effects. You need to call the state setter to update React's internal state and then re-render with the new state.
So, you need
setCount(count 1);
and not
count ;
because only the former will result in a re-render (even if you had declared count
with const
).
CodePudding user response:
The hook remains immutable in the scope of the function. When you change it, the component re-renders.
CodePudding user response:
Type const
in JS doesn't prevent you from making operations on the variable. Adding or subtraction of values will be interpreted without any issues. This the count is increasing.
However count
shorthand is written for count = count 1
where a assignment operation is taking place and it is prohibited by the type const.
CodePudding user response:
When I console.log the value of
count
, it increases by 1 even though I have declared it using const.
When you are console logging the count
state you are actually logging the unupdated current state value. In other words, nothing has changed yet. It's only at the end of the render cycle when enqueued state updates are processed that the component rerenders (i.e. calls the function body) with the updated state value.
How is it still being updated? I have a feeling it's related to the
useState
function, but I'm not sure.
Yes, the useState
hook returns the current state value and a function to call to enqueue an update to state.
const [count, setCount] = useState(0);
In the increase
callback handler the setCount
function is called with the next value you are requesting React to update the state to.
function increase() {
setCount(count 1);
}
As described above, the update is enqueued and at then end of the render cycle is processed by React and triggers the component to rerender.
Another thing is, if we can update using
count 1
, why can't we do so usingcount
?
In React we absolutely DO NOT mutate state. The count
, if it could work and not throw an error, would still be a state mutation. Trying to use count
is the same as trying to do count = count 1
which we just simply don't do in React.
In more general Javascript terms, trying to post-increment with count
while count
is declared const
would throw an error. When a variable is declared const
this only means it can't have a value reassigned to it after initialization. This doesn't mean that the value currently assigned is static/constant. If we had declared let [count, setCount] = useState(0)
then by Javascript standards doing count
is perfectly legal.
We use the React state updater functions to enqueue state updates and generally return new object/value references.