Reputation: 137
I have a following array,
const bio = [
{id: 1, name: "Talha", age: 26},
{id: 2, name: "Ayub", age: 22}
]
Here is a complete code of mine,
import './App.css';
import React, {useState} from 'react';
const bio = [
{id: 1, name: "Talha", age: 26},
{id: 2, name: "Ayub", age: 22}
]
const App = () => {
const [bioData, setbioData] = useState(bio);
const clear_function = () => setbioData([])
return (
<div className="App">
{
bioData.map((arr) =>
<>
<h3 key={arr.id}>Name: {arr.name}, Age: {arr.age}</h3>
<button onClick={() => clear_function()}>Click me</button>
</>
)}
</div>
);
}
export default App;
Now, this code hooks the whole array to useState. Whenever I click the button "Click me", it sets the state to empty array and returns empty array as a result.
But what if I want to remove a specific row of the array? I have made two buttons, each for one row. What I want to do is if I click the first button, it removes the first row from the array as well and keeps the 2nd array.
Similarly, if I want to change a specific attribute value of a specific row, how can I do that using useState hook? For example, I want to change the name attribute of the 2nd row. How is it possible to do this with useState?
And same case for addition. IF I make a form and try to add a new row into my bio array, how would I do that? I searched it up on Google, found a similar post as well but the answer given in it wasn't satisfactory and did not work, which is why I am asking this question again.
Upvotes: 3
Views: 3656
Reputation: 108
Adding a row to the array with react useState would be as simple as the following:
function addRow(objToAdd){
//get old data and add new row
let newBioData = bioData.push(objToAdd)
setBioData(newBioData)
}
To remove a specific row you would need to find the object within the bioData array, remove it and set the new bioData like so:
function removeRow(rowId){
//Filter the array by returning every object with a different Id than the one you want to remove
let newBioData = bioData.filter(function (value, index, arr){ return value.id != rowId })
setBioData(newBioData)
}
To update the state you could use the spread operator like so:
function updateRow(rowId, data){
//Iterate list and update certain row
bioData.filter(function (value, index, arr){
//Row to update
if(value.id == rowId){
return {name: data.name, age: data.age}
}else{
//Nothing to update, return current item (spread all values)
return {...value}
}
})
setBioData ([])
}
Upvotes: 1
Reputation: 1381
If I understood the question right, I think you can pass the updated object to set state and that'll be it.
To change a particular object in array, do something lie this:
// Update bio data with id = 2
setbioData(prevValue =>
[...prevValue].map(el =>
el.id === 2 ? ({...el, name:'new name'}) : el)
)
Also, you have set key
at the wrong place
Full refactored code:
const bio = [
{id: 1, name: "Talha", age: 26},
{id: 2, name: "Ayub", age: 22}
]
const App = () => {
const [bioData, setbioData] = useState(bio);
const clear_function = (id) => {
setbioData(prevValue =>
[...prevValue].map(el =>
el.id === id ? ({...el, name:'new name'}) : el)
)
}
return (
<div className="App">
{
bioData.map((arr) =>
<div key={arr.id}>
<h3>Name: {arr.name}, Age: {arr.age}</h3>
<button onClick={() => clear_function(arr.id)}>Click me</button>
</div>
)}
</div>
);
}
Upvotes: 3
Reputation: 96
import './App.css';
import React, {useState} from 'react';
const bio = [
{id: 1, name: "Talha", age: 26},
{id: 2, name: "Ayub", age: 22}
]
const App = () => {
const [bioData, setbioData] = useState(bio);
const clear_function = (i) => {
let temp = bioData.slice()
temp = temp.splice(i, 1)
setbioData(temp)
}
return (
<div className="App">
{
bioData.map((arr, i) =>
<>
<h3 key={arr.id}>Name: {arr.name}, Age: {arr.age}</h3>
<button onClick={() => clear_function(i)}>remove row</button>
</>
)}
</div>
);
}
export default App;
Same way you need to just to update a specific attribute just update that element in the temp array and do setBioData(temp)
Similarly, If you want to add another row do temp.push({id: 1, name: "Talha", age: 26}) and do setBioData(temp)
Upvotes: 1
Reputation: 11
Looks like there are 3 questions here. I'll do my best to help.
"what if I want to remove a specific row of the array?"
One way is to filter your current array and update the state with the new array.
In your example: onClick={()=>setbioData(arr.filter(row=>row.id !== arr.id))}
"if I want to change a specific attribute value of a specific row, how can I do that using useState hook?"
You will need to create a new array with the correct information and save that array to state.
In your example: [... bioData, {id:/row_id/,name:/new name/,age:/new age/}]
"IF I make a form and try to add a new row into my bio array, how would I do that" In this case, you would push a new object into your array. In your example:
setbioData(previousData=>previousData.push({id:previousData.length+1,name:/new name/,age:/new age/})
I hope this helps you, best of luck
Upvotes: 1
Reputation: 140
I'm not sure if I fully understand your question, but when you want to change the state in a functional component, you can't directly change the state object, instead you need to create a new desired state object, and then set the state to that object. for example, if you want to add a new row to your array, you'll do the following:
setbioData((currBioData) => [...oldBioData, {id: 3, name: "Bla", age: 23}]);
When you want to change the state based on the current state, there's an option to send the setState
function a callback function which accepts the current state, and then using the spread operator we add a new row to the array.
I'm not going to get into why it is better to pass setState
a function to modify current state but you can read about it in React official docs
Upvotes: 1