what will happen if usestate does not initialised with any value?
Eg: const [growth, setGrowth] = useState();
The implicit value is then (as it is for any elided function parameter) undefined.
Related
I'm using useRef to keep reference of a prop over renders during the lifetime of a component but I cannot seem to get past this type error:
Type 'MutableRefObject<any>' must have a 'symbol.iterator()' method that returns an iterator.
My code is:
const [values, setValues] = useRef<any[]>([])
Initially I was using an interface in place of any but changed to any while troubleshooting but still not working.
I have the empty array as the intial value. Not sure what I need to do here, please advise.
useRef does not work like useState. It doesn't return a value and an update callback. It just returns a ref object (type MutableRefObject).
const valuesRef = useRef<any[]>([]);
When you write const [values, setValues] = useRef<any[]>([]), you are attempting to destructure the returned value from the hook into two variables value and setValue. But you cannot destructure it because it is not an array (or an iterable). Thus you get the error:
Type 'MutableRefObject' must have a 'symbol.iterator()' method that returns an iterator.
You access the value of the ref through the .current property:
const values = valuesRef.current; // is type any[]
You update the values by setting the .current property:
valuesRef.current = [1, 2, 3];
Typescript Playground Link
React Docs: useRef
I'm using React hooks and I have the code below:
const [_va, _setva] = useState(0);
const va = useRef({current: _va});
console.log(va);
So according to the documentation, The expected value of va is an object which has a current property containing the desired value which is initially 0.
But when I run the script I got this result:
In other words, instead of the va.current containing the desired value, va.current contains another current property which contains the desired value. Which means I have to access va.current.current to access the desired value.
Does anyone know why this happens?
You've misunderstood the doc; you will set the value of the ref, and it is returned in the current property of the returned object:
const ref = useRef("foo");
console.log(ref.current) // "foo"
The purpose of useRef is to give you an object whose reference does not change, but whose value may. That value is exposed as current. You can access and reassign ref.current at will, and ref remains unchanged.
I'm using React hooks now. I've seen useState(null)[1] but I forgot where I seen it.
I wonder what's different from useState(null)?
In the docs, it says
Returns a stateful value, and a function to update it.
But what they mean is
Returns an array where the first position is a stateful value, and the second position is a function to update it.
The useState hook returns an array where the first position (index 0) is the state and the second position (index 1) is the setter for that state.
So when using useState(null)[1] you are only getting the setter for that state.
When you do
const [state, setState] = useState(null)
What you are doing is called Destructuring Assignment
And because in most cases you want to have both state and setState, destructuring makes it much easier to use than doing.
const hook = useState(null)
const state = hook[0]
const setState = hook[1]
With destructuring, you can make that with only one line which is much cleaner
And if you only want the setter, you can do it by
const setState = useState(null)[1] // only getting the setter
Just keep in mind that both are the same thing.
I wonder what's different from useState(null)?
useState(null) returns an array ([state, setState])
useState(null)[1] is accessing the returned array (setState)
The next expressions are equivalent:
const [, setState] = useState(null); // Destructuring assignment
const setState = useState(null)[1]; // Array index excess.
As useState returns an array of values, you can unpack values from the array.
Also, you can access (index into) an array item.
useState API.
I am currently learning React and React hook. A classic example of using useState is as below:
const [count, setCount] = useState(0);
My question is why the returned array is const? I think at least the value of count is changed over time.
The value returned by useState is not a const array, rather its just an array which the user has decided to declare as const. Think of the above as
const stateValue = useState(0);
const count = stateValue[0];
const setCount = stateValue[1];
So in short, the syntax const [count, setCount] = useState(0); is an Array destructuring syntax.
Not its is declared as const because you are not reassigning count or setCount to something else in your code, instead just using setCount method to update the state count.
React authors decided to return an array with state value and state setter so that you can name it anything you want instead of using a pre-decided name while destructuring.
In React State Hooks, one can write the following line to set a state variable called count and the setCount function to set the value afterwards, like below:
const [count, setCount] = useState(0);
Which is going to be the equivalent of writing:
this.state = { count: 0 };
My question is, how does the useState() function can get the name of the state variable -- count in this case, from the ES6 Destructuring Assignment statement?
Isn't the destructuing happens after the function has returned its value? Or is it possible to dynamically get the values that are being destructed, inside the function when it is invoked?
Update
Please note that I do understand that I can deconstruct to any name that I want, but how does the useState() knows what variable should go in the state, so it can be used later.
For example if I set two state variables, how does it distinguish between the two values, if the useState() function is not aware of the variable names?
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
When you use functional-components and useState
const [myCountVariable, setCount] = useState(0);
You only access your data using the myCountVariable variable. this.state isn't used.
If I understand correctly what you didn't understand is how it knows to write into 'this.state.myCountVariable' - it doesn't. The state doesn't store with the actual variable name.
Like the posts above me said, the useState assumes each time the component calls it it will call it in the same order so it returns "variable holders" based on index.
In React docs you can see they reference this in React Hook Rules:
Only Call Hooks at the Top Level
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls. (If you’re curious, we’ll explain this in depth below.)
Basically,
const [count, setCount] = useState(0);
is more accurately represented as
componentStateContainer[currentStateIndex] = myStateVariable; //React doesn't know how you named your local variable
currentStateIndex++;
return [myStateVariable, setStateMethod]
(currentStateIndex will reset to 0 when the function component is re-created)
It's returning an array that you destruct. The first index of the array is the value, the second the function. With array destructuring you can set a name for those variables
Example:
const [one, two] = ["test", () => {console.log(1)}];
console.log(one) // would be test
two() // would print out 1
More here:
https://medium.freecodecamp.org/array-destructuring-in-es6-30e398f21d10
useState returns an array, where first element is the value and second is the setter and using de-structuring you can give any name to it
For instance the above code is equivalent to
const state = useState(0);
const count = state[0];
const setCount = state[1];
Destructuring of arrays in JS is done by index, not by property name. Only the destructuring of objects is by property name.