I have an array of objects with the following format
const [type1Options, setType1Options] = useState([
{
name: "Name1",
value: "Value1",
},
{
name: "Name2",
value: "Value2",
},
]);
const [type2Options, setType2Options] = useState([
{
name: "Name1",
value: "Value1",
},
{
name: "Name2",
value: "Value2",
},
]);
I am rendering these objects category wise with copy and delete buttons per entry. Delete will delete the entry from the array, and copy will copy the clicked items content into a new entry and placed right below the clicked entry. Delete works just fine, but copy on the last entry doesn't work as expected. Can someone help?
Sandbox: https://codesandbox.io/p/sandbox/i18-demo-7594gf?file=%2Fsrc%2FApp.js%3A5%2C2-24%2C6
Utils for copy and delete functions
export const deleteItems = (list, idx) => {
const temp = [...list];
temp.splice(idx, 1);
return temp;
};
export const copyItems = (list, idx) => {
const newItem = { ...list[idx] };
const newItems = [...list.slice(0, idx + 1), newItem, ...list.slice(idx + 1)];
return newItems;
};
import { useState } from "react";
import List from "./List";
export default function App() {
const [type1Options, setType1Options] = useState([
{
name: "Name1",
value: "Value1",
},
{
name: "Name2",
value: "Value2",
},
]);
const [type2Options, setType2Options] = useState([
{
name: "Name1",
value: "Value1",
},
{
name: "Name2",
value: "Value2",
},
]);
return (
<div>
<List
type1Options={type1Options}
type2Options={type2Options}
setType1Options={setType1Options}
setType2Options={setType2Options}
/>
</div>
);
}
import Type1 from "./Type1";
import Type2 from "./Type2";
export default function List(props) {
const { type1Options, type2Options, setType1Options, setType2Options } =
props;
return (
<>
<div>
Category 1
{type1Options.map((obj, index) => (
<Type1
index={index}
obj={obj}
type1Options={type1Options}
setType1Options={setType1Options}
/>
))}
</div>
<br />
<div>
Category 2
{type2Options.map((obj, index) => (
<Type2
index={index}
obj={obj}
type2Options={type2Options}
setType1Options={setType2Options}
/>
))}
</div>
</>
);
}
import "./styling.css";
import { deleteItems, copyItems } from "./utils";
export default function Type1(props) {
const { index, obj, type1Options, setType1Options } = props;
const copyHandler = () => setType1Options(copyItems(type1Options, index + 1));
const deleteHandler = (index) =>
setType1Options(deleteItems(type1Options, index + 1));
return (
<div className="box-container">
<div className="box-header">
<h3>Index {index + 1}</h3>
<div className="box-buttons">
<button onClick={copyHandler}>Copy</button>
<button onClick={deleteHandler}>Delete</button>
</div>
</div>
<div className="box-content">
{obj.name}: {obj.value}
</div>
</div>
);
}
Issue was the mismatch of 1 and 2 in type1Options and type2Options in 2 files. here is the updated code.
List.jsx
import Type1 from "./Type1";
import Type2 from "./Type2";
export default function List(props) {
const { type1Options, type2Options, setType1Options, setType2Options } =
props;
return (
<>
<div>
Category 1
{type1Options.map((obj, index) => (
<Type1
index={index}
obj={obj}
type1Options={type1Options}
setType1Options={setType1Options}
/>
))}
</div>
<br />
<div>
Category 2
{type2Options.map((obj, index) => (
<Type2
index={index}
obj={obj}
type2Options={type2Options}
setType2Options={setType2Options}
/>
))}
</div>
</>
);
}
and type2.jsx
import React from "react";
import "./styling.css";
import { deleteItems, copyItems } from "./utils";
export default function Type2(props) {
const { index, obj, type2Options, setType2Options } = props;
const copyHandler = () => setType2Options(copyItems(type2Options, index));
const deleteHandler = () => setType2Options(deleteItems(type2Options, index));
return (
<div className="box-container">
<div className="box-header">
<h3>Index {index + 1}</h3>
<div className="box-buttons">
<button onClick={copyHandler}>Copy</button>
<button onClick={deleteHandler}>Delete</button>
</div>
</div>
<div className="box-content">
{obj.name}: {obj.value}
</div>
</div>
);
}