ES6 Add new elements to an array in state - reactjs

createNewList = (id, input) => {
const foundCard = {...this.state.cards.find(card => id === card.id)};
this.setState(foundCard.list = [...foundCard.list, input]);
};
Hello everyone
There is an array of data (list), which is stored in the state for each object (card).
Problem: I can’t seem to add a new element to this array.
The way it is set up creates only one element and change it every time. But I need to create a new one every time. I tried to create a separate array, add to it using newArray.push (input) and then do this.setState (foundCard.list = [... foundCard.list, ... newArray])`, but have the same result.
I don’t use Redux, because I just started to learn React and I store everything in state yet.
Thanks in advance for your reply.

createNewList = (id, input) => {
const newCards = this.state.cards.map(card => {
if (card.id === id) card.list = [...card.list, input];
return card;
});
this.setState({
cards: newCards
});
};

Related

Why am I mutating the original array with filter method? [React]

After executing the newData[0].id = newValue I am actually updating the react initialData state. How is that possible?
Is my understanding that filter should return a new array different than the original one, also I am not ussing the setState feature so I don't understand why the state is changing.
Because arrays are mutable. it will keep the reference to the original array even after filtering.
use the spread operator to avoid mutating the original array
const data = [...newData]
data[0].id = newValue
As per the new beta docs on updating items in array
setInitialData(prev => {
// create a new array
const withReplaced = prev.map(elem => {
if (elem.id === id) {
const newVal = //set new value
// create a new updated element
return {
...elem,
id: newVal
}
} else {
// The rest haven't changed
return elem;
}
});
return withReplaced;
})
Hope it helps
you can't update the initialData,but the you can update the son of the array.And if you don't use "setData".The views won't change.

Unable to understand setState of react js function paramters in a specific call?

setListOfPosts(curPosts => {
let newPosts = [...curPosts];
newPosts[newPosts.findIndex(p => p.id === postId)].alert = response.data;
}
});
//is curPosts an instance of array or complete array?? my listofPosts is an array of objects
Your setState call needs to return newPosts, and you're creating an array using the spread operator which is why it's coming back as an array of objects.
I'm not sure what your desired output is, but by adding a return function it will set the state:
setListOfPosts(curPosts => {
let newPosts = [...curPosts];
newPosts[newPosts.findIndex(p => p.id === postId)].alert = response.data;
return newPosts
}
});
This is untested but if your logic is correct should return an array of objects with the objects alert value updated.
Another option would be to do your logic before your setState call, by creating a a newState array and then simply updating the state with that new array without the use of the callback.
The callback function is useful if you want to add a new object to state array or do something that preserves the initial state, in your example you could do it without the callback like this:
// Create a copy of the state array that you can manipulate
const newPosts = [...newPosts]
if (data.response) {
// Add your logic to the state copy
newPosts[newPosts.findIndex(p => p.id === postId)].alert = response.data;
// Replace state with state copy
setListOfPosts(newPosts)
}
Again untested but hopefully this should help you understand the use of the callback function and the right way to use it.

Reactjs array map mutation

I have come around this topic today.
I am trying to map an array and update it like this.
const editTask = (id, newTitle) => {
const updatedTodo = [...tasks].map(task => {
task.id === id ? {...task, title: newTitle} : task
});
setTasks(updatedTodo);
};
tasks is array of objects
One of my friends have told me that there is no need to copy the original array during map. because map itself returns the new array.
But as far as I know this array is considered as 2 level deep array and it needs to copy the original array too for the update of the object.
Can someone explain to me which way is correct and which is not? I am lost.
Thanks in advance
Your friend is right: map DOES return a new array (unlike forEach)
Since you're using react-hooks, creating a new array for the updated tasks is considered redundant and the best way to achieve the same result is to do something like this:
const editTask = (id, newTitle) => {
setTasks((tasks) =>
tasks.map((task) => (task.id === id ? { ...task, title: newTitle } : task))
);
};

React Native: update an Array inside an Object

i currently have an object and inside this object i have multiple objects and Arrays. I want replace an Array inside this object with a new Array, so i thought of making a copy of the entire object and simple replace the Array i wan to change with the updated Array. My problem is i couldnt complete my code, i have the idea of how to do it but cant execute it.
setListings(listings=>
listings.map(item =>{
if(item.id === msg.id){
//console.log(item)
//console.log(item.Message)
const newMessages = [msg,...item.Messages]
//console.log(newMessages)
return console.log([msg,...item.Messages],{...item}) // just for testing purpose i
am returning a console log
to see what it will get me. Not correct.
}
return item;
})
);
So basically listings is my state variable, here console.log(item) prints out the entire object, console.log(item.Messages) prints out the current Messages Array which i want to replace, console.log(newMessages) prints out the new Messages Array which i want to replace the current Messages array with.
cartItem.map((food,index)=> {
if(food.food_id == newFoodItem.food_id && food.id == newFoodItem.id){
const AllFoodData = cartItem
AllFoodData[index] = newFoodItem
AsyncStorage.setItem('#Add_cart_Item', JSON.stringify(AllFoodData))
.then(() => {})
.catch(err => console.log(err))
ToastAndroid.showWithGravityAndOffset('Cart Replace Successfully',ToastAndroid.LONG,ToastAndroid.BOTTOM,25,50 )
}
})
So basically what i want to achieve here is to add the msg object to the existing Messages Array.
Since lsitings is an Array of objects using the .map i can spread through each object and check if the id of that object is each to my msg.id. if that is true then i want to return a copy the that specific listing and edit the Messages Array within [msg, ...item.Messages] otherwise return the existing item.
setListings(listings=> listings.map(item => {
if(item.id === msg.id) {
return {
...item,
Messages: [msg, ...item.Messages]
}
}
return item;
}));
});

How do i save my to-do app's list in local storage?

This is what I have so far: https://gist.github.com/justgoof9/f6250cdbd615bda139ef8d56375fa12c
So when I add items to the list then when I refresh the browser, I want it to still save. I want to do it with JSON but don't know how. Can anyone help me?
Yes you can achieve it by using local storage, so whenever you push something to your to Todo list, save the updated list in local storage and then when you are rendering in the UI use the data that is stored in local storage. Here is a small example to achieve this --> https://www.w3schools.com/html/html5_webstorage.asp
Hope this solved your problem.
Hi storing objects in LocalStorage is a bit tricky because LocalStorage accepts strings, but JSON.stringify() comes to the rescue! In you function addToList:
addToList = input => {
let listArray = this.state.lists;
listArray.push(input);
this.setState({
list: listArray,
userInput: ""
});
};
You want to add a LocalStorage call that saves the list from this.state into LocalStorage, like this:
addToList = input => {
let listArray = this.state.lists;
listArray.push(input);
this.setState({
lists: listArray,
userInput: ""
}, () => {
window.localStorage.setItem('savedList', JSON.stringify(this.state.lists));
});
};
And to retrieve it, you need to parse it back into an array/object, like this:
componentDidMount() {
const list = window.localStorage.getItem('savedList');
const parsedList = JSON.parse(list);
this.setState({
lists: parsedList,
})
}
Now every new item you add is saved to localStorage and is retrieved on refresh, all that is left is to apply the same logic to removing items, like this:
listOnClick = index => {
var arr = this.state.lists;
arr.splice(index, 1);
this.setState({ lists: arr }, () => {
window.localStorage.setItem('savedList', JSON.stringify(this.state.lists));
});
};
You also had a typo in addToList, you were assigning to this.state.list instead of this.state.lists

Resources