I am trying to swap the indexes of two elements inside of an array, which is contained inside an object as a property. In my CodeSandbox example below, whenever I try to click on the second "^" button, it gives me the error TypeError: arr.container.map is not a function. I’ve tried changing the object property containing the array by creating a function that swaps the indexes and I have also tried to use the splice array function to swap them as well. But no matter what, I keep getting the same error.
A demonstration of the error I’m getting can be seen here: https://codesandbox.io/s/gallant-cohen-rj399q?file=/src/App.js
import { useState } from 'react'
export default function App() {
const [arr, setArr] = useState({container: [{num: 0}, {num: 1}]})
return (
<div>
{arr.container.map((element, index) => (
<div>
<button onClick={() => setArr(arr => {
return {
...arr,
["container"]: () => {
let copy = [...arr.container];
const temp = copy[index];
copy[index] = copy[(index - 1)];
copy[(index - 1)] = temp;
return [...copy];
}
}
})}>^</button>
<p>{ element.num }</p>
</div>
))}
</div>
);
}
>Solution :
In your buttons onClick:
<button onClick={() => setArr(arr => {
return {
...arr,
["container"]: () => {
let copy = [...arr.container];
const temp = copy[index];
copy[index] = copy[(index - 1)];
copy[(index - 1)] = temp;
return [...copy];
}
}
})}>^</button>
you are setting arr to an object whose container property is a function. And functions don’t have a map property.
I’m not sure why you felt you needed a function here. You’re already using the functional form of setArr, so you can do this manipulation in the body of that function. It might end up looking something like this:
<button onClick={() => setArr(arr => {
let copy = [...arr.container];
const temp = copy[index];
copy[index] = copy[(index - 1)];
copy[(index - 1)] = temp;
return {
...arr,
container: copy
}
})}>^</button>