when i try to delete an item from the column and return the new column, the setColumns replace only the first column, the data in the column is correct but the placement is wrong
this is the initial state
this is the result expected after deleting the item
this is the result after calling the delete function
The new in progres column does show the wanted outcome but it didn’t replace the right column
How can i make it work properly?
this is the code for this app
const [orders, setOrders] = useState([]);
useEffect(() => {
props.fetchOrder(setOrders)
},[])
const columnsFromBackend = {
newOrder: {
name: "Requested",
items: orders,
},
inProgres: {
name: "In Progres",
items: [],
},
finished: {
name: "Finished",
items: [],
},
deliverd: {
name: "Deliverd",
items: [],
},
}
const [columns, setColumns] = useState([])
console.log(columns);
useEffect(() => {
setColumns(columnsFromBackend);
console.log("test");
}, [orders]);;
i thinks the problem is with the useEffect hook that calls setColumns for the first time but I’m not sure.
this is the code for the delete function
const deleteItem = (item, columns, column, setColumns, index) => {
const itemId = item._id
const columnsArray = columns
const copyColumns = [...column.items]
console.log(typeof(copyColumns));
copyColumns.splice(index, 1);
console.log(columnsArray)
setColumns({
...columns,
["newOrder" || "inProgress" || "finished" || "delivered"]:{
...column,
items:copyColumns
}});
dispatch(deleteOrder(item));
};
this is how I render the columns
{Object.entries(columns).map(([_id, column]) => {
return(Objects)
}
this is the parameters that I passed to the delete function
const deleteItem = (item, columns, column, setColumns, index) => {}
how can I make the code return the column to the right position?
I was able to make my code work, it isn’t best practice but it’s works.
i needed to refer to each column key so to each column object I have added a property columnNumber, and each individual column got a different number
and anew key that much the property columnNumber
const columnsFromBackend = {
1: {
columnNumber: 1,
name: "Requested",
items: orders,
},
2: {
columnNumber: 2,
name: "In Progres",
items: [],
},
3: {
columnNumber: 3,
name: "Finished",
items: [],
},
4: {
columnNumber: 4,
name: "Deliverd",
items: [],
},
}
in the delete function I have added const columnNumber = column.columnNumber
so i have a verbal to use in the setColumns function
this is the setColumns function
setColumns( prevState => {
return{
...prevState,
...columns,
[columnNumber]: {
columnNumber: columnNumber,
name: column.name,
items:copyColumns}
}
})
and it works the results are returned as expected
Related
I've got a counter array, containing 3 objects.
const [counter, setCounter] = useState([
{ id: 0, count: [] },
{ id: 1, count: [] },
{ id: 2, count: [] }
])
Theres then 3 buttons that when pressed call the following function.
const update = (i, text) => {
setCounter(currCount =>
currCount.id === i
? { id: i, count: [...counter[i].count, text] }
: currCount
);
};
The buttons pass "i" which is 0,1,2 corresponding to the 3 object ids and "text" which is the error text.
The function should update the specific object from the array adding the new error text to that id's count array.
I cant seem to get this to work though, it keeps returning undefined.
Any help is appreiciated.
The useState dispatch function (setCounter in your case) replaces the whole state with the value it is provided with.
In your example, you need to recreate the whole array like so:
const update = (i, text) => {
setCounter(currCounter =>
[
...currCounter.filter(count => count.id !== i), // the old counter state without the one we want to change
{ id: i, count: [...currCounter[i].count, text] }
]
);
};
this is my code
const [state, setState] = useState(
[{id: 1, key:""}, {id: 2, key:""}, {id: 3, key:""}]
)
i want to to change "key" state
im confuse
now im using
setState(
[...state].map((data, index) => {
if (data.id === state[index].id) {
return {
...data,
key: result,
};
} else return data;
}),
);
}
result variable came from result when i fetching data.
result is a random string
If your data structure is always going to be in that order data.id === state[index].id doesn't really achieve much.
For example:
when data.id is 1 the index will be 0. And state[0].id is 1.
when data.id is 2 the index will be 2. And state[1].id is 2.
etc.
It just sounds like you want to iterate over all the objects in state and update each key value with that random string you mentioned in the comment section. There's no need to make a copy of state since map already returns a new array ready for setState to use.
function setState(mapped) {
console.log(mapped);
}
const state = [{ id: 1, key: '' }, { id: 2, key: '' }, { id: 3, key: '' }];
const result = 'random';
const mapped = state.map(data => {
return { ...data, key: result };
});
setState(mapped);
I have a function which gets the user input and update the array if the same key is available already. with the help of this article
This is how it looks;
const handleClickYes = (question) => {
// find if question is in the data array
const hasQuestion = data.find(({ parentId }) => question.id === parentId)
const indexOfQuestion = data.indexOf(hasQuestion)
if (hasQuestion) {
// update the value with specific selected index in the array.
data[indexOfQuestion] = { question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }
} else {
setData((data) => data.concat({ question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }))
}
localStorage.setItem('deviceReport', JSON.stringify(data))
}
I'm using localStorage to persist the state
const deviceReport = localStorage.getItem('deviceReport') ? JSON.parse(localStorage.getItem('deviceReport')) : []
const [data, setData] = useState(deviceReport)
Here the problem is if I use setData then it updates instantly but on replacing the array
at this part
data[indexOfQuestion] = { question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }
it dosent update the mapped data on JSX portion. How can I configure it to update it happen in setState. ? Or any other better option to update the array.
You're not calling setState() within the first half of your if block. Also, never mutate state directly. Make a mutable copy, like so:
const handleClickYes = (question) => {
// find if question is in the data array
const hasQuestion = data.find(({ parentId }) => question.id === parentId);
const indexOfQuestion = data.indexOf(hasQuestion);
// copy data to mutable object
let newData = [...data];
if (hasQuestion) {
// update the value with specific selected index in the array.
newData[indexOfQuestion] = {
question: question.if_yes,
parentId: question.id,
userChoice: "YES",
child: [],
};
} else {
// concat existing data with a new question
newData = [
...newData,
{
question: question.if_yes,
parentId: question.id,
userChoice: "YES",
child: [],
},
];
}
localStorage.setItem("deviceReport", JSON.stringify(newData));
setData(newData);
};
I have a component that render data from a store in vuex
the component has a computed status when a search query has been written it will filter that store state which is kommunhanteringItems to search for a customer and here i have a problem which is the computed status will mutate the state in the store which i do not want it to do that.
State in the store which is this.$store.state.todos.kommunhanteringItems:
kommunhanteringItems: [
{
gId: 1,
gtitle: 'Group1',
items: [
{cid: 1, customer: 'Vicotria Nils'},
{cid: 2, customer: 'Mona Andersson'}
]
},
{
gId: 2,
gtitle: 'Group2',
items: [
{cid: 3, customer: 'Jacob Ström'},
{cid: 4, customer: 'Magdalin eriksson'}
]
}
]
Component computed:
SearchInTables() {
let k = this.$store.state.todos.kommunhanteringItems
if (this.SearchQuery != '') {
let SearchFilter = []
let self = this
k.forEach(function (x) {
let items = x.items
let filter = items.filter((item) => {
return item.customer.toUpperCase().includes(self.SearchQuery.toUpperCase())
})
x.items = filter
SearchFilter.push(x)
})
return SearchFilter
} else {
return k
}
},
The problem is that you are writing to x which is an object in an array in the store, when you do x.items = filter.
To avoid this, you need to create a copy of x, and replace items. See below for an example of doing this with Object.assign
SearchInTables() {
let k = this.$store.state.todos.kommunhanteringItems
if (this.SearchQuery != '') {
let SearchFilter = []
let self = this
k.forEach(function (x) {
let filter = x.items.filter((item) => {
return item.customer.toUpperCase().includes(self.SearchQuery.toUpperCase())
})
SearchFilter.push(Object.assign({}, x, { items: filter })
})
return SearchFilter
} else {
return k
}
}
I am trying to increment the productQuantity of an item that has been pushed into an array. If the productID of the item matches that of an item already in the array, the quantity should be increased.
export function ADD_ITEM(state, product) {
// state.isAdded = true;
const added = state.storeCart.find(product => product ===
product.productID)
if (!added) {
state.storeCart.push(product)
} else {
product.productQuantity++
}
It looks like there are a few issues.
The product argument in your find callback function is shadowing the product argument from the ADD_ITEM function. We'll change this to p.
In the find callback, you should check if the productID of p is equal to that of the provided product.
It seems that you just want to push the entire product onto the storeCart, not push each individual property.
You should increment productQuantity on added since that's a ref to the actual existing item in state.
export function ADD_ITEM(state, product) {
const added = state.storeCart.find(p => p.productID === product.productID);
if (!added) {
state.storeCart.push(product);
} else {
added.productQuantity++;
}
}
Just to demonstrate that this is functional, here's a bare-bones example.
function ADD_ITEM(state, product) {
const added = state.storeCart.find(p => p.productID === product.productID);
if (!added) {
state.storeCart.push({...product});
} else {
added.productQuantity++;
}
}
const state = {
storeCart: []
}
const hat = { productID: 1, name: "hat", productQuantity: 1 };
const jacket = { productID: 2, name: "jacket", productQuantity: 1 };
const shoes = { productID: 3, name: "shoes", productQuantity: 1 };
ADD_ITEM(state, hat);
ADD_ITEM(state, jacket);
ADD_ITEM(state, shoes);
ADD_ITEM(state, jacket);
console.log(state);