How to put objects in empty array with React Hooks

Asked

Viewed 459 times

3

I have the following data set:

const dados = [5, 10, 15, 20, 25, 50, 90];
const colors = [
  "#52DF9A",
  "#FFCE1C",
  "#3570BD",
  "#3570BD",
  "#00B894",
  "#FB6B32",
];

And I’ve got the following state:

const [data, setData] = useState([{}]);

I need to go through the data and put a data with a respective color, so that the "given" state is as follows:

data = [
  { valor: 5, color: "#52DF9A" },
  { valor: 10, color: "#FFCE1C" }, 
  // ...
];

I did it this way with useEffect:

useEffect(() => {
  dados.forEach((dado, i) => {
    setData((prev) => {
      return [...prev, { valor: dado, color: colors[i] }];
    });
  });
}, []);

But the problem is, when I do it this way, the first position is occupied by an empty object ({}), and I need the data to start at first position. How can I solve this?

'Cause if I do this:

const [data, setData] = useState([]);

Makes a mistake.

  • 1

    In theory it was not to const [data, setData] = useState([]) give error. I could say in more detail what happens?

  • When I put only [ ] it says this: Argument of type '(Prev: Never[]) => { value: number; color: string; }[]' is not Assignable to Parameter of type 'Setstateaction<Never[]>'.

  • 1

    If you want to understand why this happens, you can open a another question. Just don’t forget to create a [mcve].

1 answer

6


The problem is that you boot data as a array which already has the first element filled in. In this case, by a literal object "empty":

const [data, setData] = useState([{}]);
//                                ↑↑
//                Objeto "vazio" no primeiro elemento

That way, when the logic you put in the useEffect is executed, the first element will be kept in the array, since you at all times maintains the previous state in the array:

useEffect(() => {
  dados.forEach((dado, i) => {
    setData((prev) => {
      return [...prev, { valor: dado, color: colors[i] }];
    });
  });
}, []);

Note that the ...prev is doing just that - keeping the previous state.


One solution is to initialize the state data as a array emptiness:

const [data, setData] = useState([]);

If for some reason this is not possible (which it should be), you can modify the logic of useEffect:

useEffect(() => {
  const newData = dados.map((valor, i) => ({
    valor,
    color: colors[i]
  }));

  setData(newData);
}, []);

An example of array that newData will be:

const dados = [5, 10, 15, 20, 25, 50, 90];
const colors = [
  "#52DF9A",
  "#FFCE1C",
  "#3570BD",
  "#3570BD",
  "#00B894",
  "#FB6B32",
];

const newData = dados.map((valor, i) => ({
  valor,
  color: colors[i]
}));

console.log(newData);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.