6π
β
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);
13π
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);
}, []);
5π
You should write setNames([...names, ...newNames]);
and you missed a comma in the const array after age: 23
0π
Try this:
if (contentLoading) {
setNames( () => { return [...names, array.map((item) => item.name)] });
}
Source:stackexchange.com