score:5

Accepted answer

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);

score:0

try this:

if (contentloading) {
  setnames( () => {  return [...names, array.map((item) => item.name)] });
}

score:5

you should write setnames([...names, ...newnames]);

and you missed a comma in the const array after age: 23

score:7

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);
}, []);

Related Query

More Query from same tag