如何更新嵌套在对象中的对象数组的元素?

huangapple go评论63阅读模式
英文:

how to update element of an array of objects nested in an object?

问题

如何更新嵌套在对象内的对象数组?我尝试使用 useState 钩子来创建此对象。

这是我的代码:

const [hotelForm, setHotelForm] = useState({
  HotelLocation: "",
  CheckInOn: "",
  CheckOutOn: "",
  rooms: [
    {
      roomNo: 1,
      noOfPersons: 2,
      ageOfPerson1: 0,
      ageOfPerson2: 0,
    },
  ],
  rooms: props.rooms, // 这里的代码可能有问题,应该检查一下
});

在这里,我尝试在表单输入字段值更改时更新房间数组的值。在相同的房间数组中,可以添加其他房间对象(使用roomNo、noOfPersons等创建的对象)。

如何使用状态更新此对象数组?如果可能的话,我也想知道如何使用纯JavaScript来做这件事,而不是React。

英文:

How can I update an array of objects nested inside an object? I am trying to create this object using the useState hook.

This is my code:

	const [hotelForm, setHotelForm] = useState({
		HotelLocation: "",
		CheckInOn: "",
		CheckOutOn: "",
		
		 rooms: [
		 	{
		 		roomNo: 1,
		 		noOfPersons: 2,
		 		ageOfPerson1: 0,
		 		ageOfPerson2: 0,
		 		
		 	},
		 ],
		 rooms: props.rooms,
	});

Here, I am trying to update the value of the rooms array when the form input field value changes. In the same rooms array, other room objects (objects made using roomNo, noOfPersons, etc.) can be added.

How can I update this array of objects using state? If possible, I would also like to know how to do it using vanilla JavaScript, not React.

答案1

得分: 1

这将是使用一个 reducer 的良好案例(https://react.dev/reference/react/useReducer),它有助于处理复杂的状态和/或不同的状态更新。

另外,将房间的数据结构更改为一个映射(map)可以更容易地从/向状态中读取/写入数据,而不必每次都遍历所有的房间。

const reducer = (state, action) => {
   const {type, roomId, ...roomData} = action;
   switch(type) {
     case 'updateRoom': return {
        ...state,
        rooms: {
           ...state.rooms,
           [roomId]: {
             ...state.rooms[roomId],
             ...roomData
           }
        }
     }
   }
};

const defaultState = {
  HotelLocation: "",
  CheckInOn: "",
  CheckOutOn: "",
  rooms: {
     1: {
        noOfPersons: 2,
        ageOfPerson1: 0,
        ageOfPerson2: 0,
     }
  }
}

const [state, dispatch] = useReducer(reducer, defaultState);

以后,如果你需要更新某些内容,你可以像这样调用:

dispatch({type: 'updateRoom', roomId: 1, ageOfPerson1: 20});

根据你的需求,你可以在 reducer 函数中添加更多的情况,例如添加新的房间、删除房间等。

这段代码不是完全安全的,你需要添加一些错误处理。
这里 你可以找到更多关于 reducers 和复杂状态的示例。

英文:

This would be a good case for using a reducer (https://react.dev/reference/react/useReducer) which helps to deal with complex states and/or different state updates.

Also, changing the data structure of the rooms to a map makes it easier to read/write data from/to your state and you don't have to iterate over all of your room every time.

const reducer = (state, action) => {
   const {type, roomId, ...roomData} = action;
   switch(type) {
     case 'updateRoom': return {
        ...state,
        rooms: {
           ...state.rooms,
           [roomId]: {
             ...state.rooms[roomId],
             ...roomData
           }
        }
     }
   }
};

const defaultState = {
  HotelLocation: "",
  CheckInOn: "",
  CheckOutOn: "",
  rooms: {
     1: {
        noOfPersons: 2,
        ageOfPerson1: 0,
        ageOfPerson2: 0,
     }
  }
}

const [state, dispatch] = useReducer(reducer, defaultState);

Later, if you need to update sth. you can call sth like this:

dispatch({type: 'updateRoom', roomId: 1, ageOfPerson1: 20});

You can add more cases to your reducer function depending on your needs. e.g. adding a new room, removing one, etc.

This code is not fail-safe, you'll need to add some error handling.
Here You can find some more examples of reducers & complex states.

huangapple
  • 本文由 发表于 2023年6月2日 03:56:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76385283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定