Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing array of React components to useState returns empty array

Very simple code here. I'm wondering if this is the expected outcome. I'm upgrading an npm module and it requires I pass these items to useState which was not previously necessary. Unfortunately, I guess this can't be done with useState? Am I right? I'd love to be wrong.


Where props.items contains an array of class-based React components, useState returns an empty array:

const [items, set] = useState(props.items);

Input:

enter image description here

Output:

enter image description here

*Note, images use prop spreading inside of array because I'm out of ideas besides, rework all the things.

like image 949
Slbox Avatar asked Feb 06 '20 19:02

Slbox


People also ask

Does useState return array?

Going back to the useState hook, it returns its variables in an array because it is likely that we're going to use that hook more than once per component. We need to be able to instantiate that hook several times but each instance has a different name. Example: const [val, setVal] = useState(0);

How do you create an empty array in useState?

We can also create a state based on an empty array: import { useState } from "react"; const [products, setProducts] = useState([]); Now, let's see how to add/push a new value to the array state. Since the state is immutable, we can't simply push a new value value to the array like we do normally in plain JavaScript.

Why do we pass empty array in useEffect?

Empty dependency array So what happens when the dependency array is empty? It simply means that the hook will only trigger once when the component is first rendered. So for example, for useEffect it means the callback will run once at the beginning of the lifecycle of the component and never again.


2 Answers

This is not really recommanded you better do it in the useEffect because Props in Initial State is an anti-pattern.

const [items, setItems] = useState([]);


useEffect(() => {
    setItems(props.items);
  },[props.items]);
like image 124
G.aziz Avatar answered Oct 14 '22 05:10

G.aziz


You should have no issues with using react element array as the input to useState. But, whenever you initialize your state with props coming from parent, you also need to re-update your state once the prop from parent changes. Otherwise it will point to the old state passed down from parent in the first pass. And the way to do that is to do a setItems with useEffect hook

useEffect(() => {
   setItems(props.items)
}, [props.items])

btw this will only check for the reference equality between the old and the new array, if you want to do deep comparison, you should probably be using something like use-deep-compare-effect

like image 30
Moinul Hossain Avatar answered Oct 14 '22 05:10

Moinul Hossain