I have a problem, I'm trying to add/update the data object after selecting an item.
here's the code:
const [roomDept, setDept] = useState([{ code: null, dept: null }]);
const [department, setDepartment] = useState([]);
const appendRoomDpt = () => {
setRoomDept(array => [...array, { code: null, dept: null }]);
}
return (
<div>
<ButtonGroup>
<IconButton icon={<Icon icon="plus" />} onClick={() => appendRoomDept()} />
</ButtonGroup>
roomDept.map((item, index) => (
<div key={index} className="flex">
<div className="flex-1 pb-2">
<SelectPicker
placeholder={"Select Room"}
data={room['data']}
labelKey="name"
valueKey="code"
style={{ width: '120px' }}
cleanable={false}
disabledItemValues={roomDept.map(x => x.code)}
onChange={(value) => {
const id = room['data'].filter(x => x.code === value).map(x => x.id);
(function getDepartment() {
useDepartments.getAll({ room: id, length: 9999 }).then(response => {
//Here's what I'm trying to do
let dept = [...department];
dept[index] = response['data']['data']
setDepartment(department);
console.log(department)
});
})()
}}
value={roomDept[index].code}
/>
</div>
</div>
))
</div>
)
assuming roomDept
I click the button add. then there's a two selection.
after that when I try to select on the first select field it will append on the department, but when I try to select on the second field it will just replace instead of adding. for example
I select on the first select field. the output is like this.
[{code: 'r1', name: 'room 1'}]
then when I try to select on the second select field the output just replace on it
[{code: 'r2', name: 'room2'}]
instead it will add, where it should be like this.
[{code: 'r1', name: 'room 1'},{code: 'r2', name: 'room2'}]
on the update side it should update base on the index and it will not add/append.
CodePudding user response:
Always remember these three lines to update a state that stores an array
Break object to create a new one. Update that new object with the new value. setState with that new object.
It goes like so:
let newObj = { ...state }
newObj.keyToBeUpdated = updatedArray
setState(newObj)
That's it.
CodePudding user response:
Since you are trying to essentially update the state, could you just concat the original state array with the new one on click? Something along the lines of:
const appendRoomDpt = (array) => {
setRoomDept( [...roomDept,...array]);
}
CodePudding user response:
I recommend to use the useReducer.
const [todos, dispatch] = useReducer(reducer, []);
function reducer(state, action) {
switch (action.type) {
case "add":
return [...state, action.payload];
case "remove":
return state.filter(td => action.payload !== td.id);
case "cancel":
return []
default:
return state;
}
}
const addItem = (data) => {
if (undefined === todos.find((item => item.type_id === data.type_id && item.type === data.type))) {
const item = {
id: new Date().toString(),
...data
};
dispatch({ type: "add", payload: item });
}
};
const removeItem = id => {
dispatch({ type: "remove", payload: id });
};