Home > Mobile >  add array to array state in react hooks gives a number
add array to array state in react hooks gives a number

Time:09-12

i declare a Array sate and want to add some Arrays in it like :

const [number, setNumber] = useState(3);
const [TimePickerList, setTimePickerList] = useState([]);
useEffect(() => {
        
        for(var i = 0; i < number ; i  ) { 
           setTimePickerList(TimePickerList.push([]))
           
        }
        console.log(TimePickerList); // it gives me an array like this : [[],[],[]]
    }, [number])

but when i get log from TimePickerList in another function it gives me a number (3). and i lost my arrays in my array state (I expected something like this : [[],[],[]] But While gives me the length of the array) I also used concat() but it gives me an empty Array and doesn't add my Arrays

CodePudding user response:

You can push the values in an empty array. Then set it to your state

    const [number, setNumber] = useState(3);
    const [TimePickerList, setTimePickerList] = useState([]);
    useEffect(() => {
            var list = []
            for(var i = 0; i < number ; i  ) { 
               list.push(i)
            }
            setTimePickerList(list)
        }, [number])
           

CodePudding user response:

  1. Don't mutate the state object, it messes up change detection,
  2. and the value of the expression someArray.push(someValue) is someValue.

Instead do something like

let newList = [...TimePickerList];

for(let i = 0; i < number; i  ) {
    newList = [...newList, []];
}

setTimePickerList(newList);

CodePudding user response:

The state works a bit differently as compared to normal variables and shouldn't be updated directly (for reasons mentioned here output

But if you want to set value based on a prev value it's better to pass a callback into setter function which receives current state value

Another point - it's better to call setter function once

const [number, setNumber] = useState(3);
const [timePickerList, setTimePickerList] = useState([]);

useEffect(() => {
  setTimePickerList((prev) => {
    const list = [...prev];
    for(let i = 0; i < number ; i  = 1) { 
      list.concat([]);
    }

    return list;
  })
}, [number])

CodePudding user response:

The fastest way to push an element to a state containing an array is using a callback:

const [number, setNumber] = useState(3);
const [TimePickerList, setTimePickerList] = useState([]);

useEffect(()=>{
 let list = [];
 for(let i = 0; i < number ; i  ) { 
   list.push([])
 }
 setTimePickerList((currentArray) => [...currentArray,...list])
},[number])

The only thing I'm guessing is: why adding empty arrays? You know that filling up these arrays will be a nightmare and since you are using a complicated data structure maybe useState is not what you want to use?

NOTICE:

Since changes of state are not performed synchronously you cannot watch the updates to TimePickerList directly in the first useEffect. To see how it changes add a second useEffect:

useEffect(()=>{
  console.log(timePickerList);
},[timePickerList])
  • Related