I have an array of objects like this
const array = [
{
age: 13,
name: "Housing"
},
{
age: 23
name: "Housing"
}
]
I want to use this array to create chart so I need to create two arrays from names
and ages
. Then I want to pass it down as props to another component
So far I came up with this in my parent component
const [names, setNames] = useState([]);
useEffect(() => {
createArray();
}, []);
const createArray = () => {
if (contentLoading) {
const newNames= array.map((item) => item.name);
setNames([...names, newNames]);
}
};
The problem here is that newNames
is being created but when I set it with hook setNames
, names
is not updated, it is still empty. I'm not sure what am I doing wrong.
All the help will be much appreciated.
When updating your state using hooks, it's best to use callbacks.
Try updating your code:
setNames(prevNames => [...prevNames, ...newNames])
This works in the same way that prevState
worked with setSate()
.
On to your solution, you can set the initial state within useState()
:
const array = [
{
age: 13,
name: "Housing"
},
{
age: 23,
name: "Housing"
}
];
const [names, setNames] = useState(() => array.map(item => item.name));
useEffect(() => {
console.log(names);
}, []);
You should have the useEffect()
subscribe to both the contentLoading
and array
props, so it runs whenever there is a change to either, instead of running a single-time after the first mount.
Working code and sandbox: https://codesandbox.io/s/mutable-mountain-wgjyv
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const array = [
{
age: 13,
name: "Housing"
},
{
age: 23,
name: "Housing"
}
];
const App = () => {
const [loading, setLoading] = useState(false);
useEffect(() => {
setTimeout(() => {
setLoading(true);
}, 2000);
}, []);
return <Child array={array} contentLoading={loading} />;
};
const Child = ({ array, contentLoading }) => {
const [names, setNames] = useState([]);
useEffect(() => {
createArray();
}, [contentLoading, array]);
const createArray = () => {
if (contentLoading) {
const newNames = array.map(item => item.name);
setNames([...names, ...newNames]);
}
};
return (
<div>
{names.map(name => (
<div>{name}</div>
))}
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With