Reputation: 277
In a React project, I want to club certain records into an empty array, to pass into some function. So, on check of checkbox component I'm able to get the id of the record which I want to compare it with the array of data. My concern is to push all the checked records to newly created empty array, to pass it to some function. I have gone through various posts but, didn't get any satisfactory result. Please refer to the following code.
const newAllData = [{testId:123, dataId:"44", cycleId:"5050", asset:"N"},
{testId:323, dataId:"54", cycleId:"6660", asset:"N"},
{testId:444, dataId:"44", cycleId:"4340", asset:"Y"},
{testId:134, dataId:"40", cycleId:"5150", asset:"N"},
{testId:222, dataId:"42", cycleId:"5050", asset:"Y"},
{testId:552, dataId:"38", cycleId:"3244", asset:"Y"},
]
const [newArray, setNewArray] = useState([])
// Here I get id of the reocord checked
const getArray = (id) => {
//Here I find that particular record from data above
const newObj = newAllData?.find(d => d.testId == id);
var arrayData = [];
arrayData.push(...newObj);
setNewArray(arrayData)
}
console.log("NEW ARRAY", newArray)
return <>
<CheckboxComp getArrayData={getArray} />
</>;
Here only one record is populating in the newArray. What is the right approach to get all the records.
Upvotes: 1
Views: 599
Reputation: 63589
When you set the state with the found object you need to include the previous state:
setNewArray([...newArray, found]);
BUT: you also need to include a condition based on whether the box is checked on or not. If it's checked add it to the state as above. If it's not checked filter
it from the newArray
state.
const { useEffect, useState } = React;
// Pass in some data
function App({ data }) {
// Set the state
const [ newArray, setNewArray ] = useState([]);
function handleChange(e) {
// Get `value` and `checked` from the box
const { value, checked } = e.target;
// If the box is checked add it to the state
// Note: we coerce the value to a number from a string
// because we use a equality check `===`, and the value of
// `testId` is a number
if (checked) {
const found = data.find(obj => obj.testId === +value);
if (found) setNewArray([...newArray, found]);
}
// If the box is not checked remove it from the state
if (!checked) {
const filtered = newArray.filter(obj => obj.testId !== +value);
setNewArray(filtered);
}
}
// Log the change in state for clarification
useEffect(() => {
console.log(JSON.stringify(newArray));
}, [newArray]);
return (
<div>
<CheckboxComp
data={data}
handleChange={handleChange}
/>
</div>
);
}
function CheckboxComp({ data, handleChange }) {
return (
<div>
{data.map(obj => {
const { testId } = obj;
return (
<label for={testId}>
{testId}
<input
name={testId}
type="checkbox"
value={testId}
onChange={handleChange}
/>
</label>
);
})}
</div>
)
}
const data=[{testId:123,dataId:"44",cycleId:"5050",asset:"N"},{testId:323,dataId:"54",cycleId:"6660",asset:"N"},{testId:444,dataId:"44",cycleId:"4340",asset:"Y"},{testId:134,dataId:"40",cycleId:"5150",asset:"N"},{testId:222,dataId:"42",cycleId:"5050",asset:"Y"},{testId:552,dataId:"38",cycleId:"3244",asset:"Y"}];
ReactDOM.render(
<App data={data} />,
document.getElementById('react')
);
body { font-size: 1.1em; }
label { margin-right: 0.5em; padding: 0.2em; }
label:hover { background-color: #ffffa0; }
[type="checkbox"]:hover { cursor: pointer; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 1
Reputation: 96
try this:
const getArray = (id) => {
const checkedItem = newArray.find(item => item.testId === id);
let targetArr = [];
if (checkedItem) {
targetArr = newArray.filter(item => item.testId !== id);
} else {
targetArr = [...newArray, checkedItem]
}
setNewArray(targetArr)
}
Upvotes: 0
Reputation: 9
Your are using find
in getArray
function which returns only the first element in the provided array. Try using filter
.
Documentation for find
Upvotes: 0
Reputation: 545
please assign var arrayData = []; in outside the getArray function
Upvotes: 0
Reputation: 2341
You can easily make and array from object with Array.from()
method :
Array.from(object, (element, index) => { /* … */ } )
Upvotes: 0