Reputation: 1276
I'm trying to fill an object with values that I'm getting from an array of objects but it's not working as expected.
This is a simplified code example
https://codesandbox.io/s/crazy-nobel-c7xdb?file=/src/App.js
import "./styles.css";
import React, { useEffect, useState } from "react";
export default function App() {
const [fieldsValues, setFieldsValues] = useState({});
const items = [{ value: "a" }, { value: "b" }, { value: "c" }];
useEffect(() => {
items.map((item, index) => {
return setFieldsValues({
...fieldsValues,
[index]: item.value
});
});
}, []);
return (
<div className="App">
<h2> {` fieldsValues = ${JSON.stringify(fieldsValues)}`} </h2>
</div>
);
}
I want the fieldsValues to return this:
{
0: "a",
1: "b",
2: "c"
}
What I'm getting now:
fieldsValues = {"2":"c"}
Upvotes: 0
Views: 923
Reputation: 192287
To create the object map the array to [index, value]
pairs, and convert to an object with Object.fromEntries()
:
const items = [{ value: "a" }, { value: "b" }, { value: "c" }];
const result = Object.fromEntries(items.map(({ value }, index) => [index, value]))
console.log(result)
However, the way you are using the array, and then need to set the state doesn't actually makes sense in the react context.
If the array is a prop, you should add it to useEffect
as a dependency:
const arrToObj = items => Object.fromEntries(items.map(({ value }, index) => [index, value]))
export default function App({ items }) {
const [fieldsValues, setFieldsValues] = useState({});
useEffect(() => {
setState(() => arrToObj(items))
}, [items]);
...
If it's a static array, set it as the initial value of setState
:
const arrToObj = items => Object.fromEntries(items.map(({ value }, index) => [index, value]))
const items = [{ value: "a" }, { value: "b" }, { value: "c" }];
export default function App({ items }) {
const [fieldsValues, setFieldsValues] = useState(() => arrToObj(items));
...
Upvotes: 1
Reputation: 99
By your way It would be like this
useEffect(() => {
let test={}
items.map((item, index) => {
return setFieldsValues((prev)=>{
return {
...prev,
[index]: item.value
}
});
});
}, []);
Upvotes: 0
Reputation: 10111
You fix it by doing this
useEffect(() => {
items.map((item, index) => {
return setFieldsValues((prev) => ({
...prev,
[index]: item.value,
}));
});
}, []);
Better way of doing this is
useEffect(() => {
const data = items.reduce(
(prev, item, index) => ({ ...prev, [index]: item.value }),
{}
);
setFieldsValues((prev) => ({ ...prev, ...data }));
}, []);
Upvotes: 3