You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Redux Reducer中添加对象?Next.js多表单输入问题

How to Update Redux State as an Array of Objects for Multi-Form Inputs in Next.js

Let's fix your Redux state handling to match the logic you already have working with useState. The core issue here is that your current reducer isn't set up to handle individual input updates the way your local state does, and your dispatch call was passing incorrect data.

Here's what you need to change:

1. Update Your Redux Slice to Handle Item Updates

Instead of a generic setArr reducer that tries to push to the array, create a reducer that mimics the exact logic from your useState updater. Redux Toolkit uses Immer under the hood, so you can safely modify the state directly (it handles immutable updates for you).

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  arr: []
};

export const arrSlice = createSlice({
  name: "arrS",
  initialState,
  reducers: {
    // This reducer handles adding/updating/removing items based on input value
    updateArrItem: (state, action) => {
      const { name, val } = action.payload;
      const existingItemIndex = state.arr.findIndex(item => item.name === name);

      if (val === "") {
        // Remove the item if the input is cleared and it exists
        if (existingItemIndex !== -1) {
          state.arr.splice(existingItemIndex, 1);
        }
      } else {
        if (existingItemIndex !== -1) {
          // Update the existing item's value
          state.arr[existingItemIndex] = { name, val };
        } else {
          // Add a new item if it doesn't exist
          state.arr.push({ name, val });
        }
      }
    },
    // Optional: Keep this if you need to set the entire array at once (e.g., initialization)
    setArr: (state, action) => {
      state.arr = action.payload;
    }
  }
});

export const { updateArrItem, setArr } = arrSlice.actions;
export default arrSlice.reducer;

2. Fix the Dispatch Call in Your Component

Your original dispatch(setRooms(...amen)) was incorrect because you were spreading the array as individual arguments, but your reducer expected a single payload. Instead, dispatch the new updateArrItem action with the input's name and value directly.

You can also remove the local useState if you want to rely entirely on Redux for state management (no need to sync both):

import { useSelector, useDispatch } from 'react-redux';
import { updateArrItem } from '../path/to/your/arrSlice'; // Adjust the path to your slice

// ...

const dispatch = useDispatch();
// Get the current state from Redux
const amen = useSelector(state => state.arrS.arr); // Make sure this matches your store's structure

const updateVal = (e, type) => {
  const inputValue = e.target.value;
  // Dispatch the action with the name of the amenity and its value
  dispatch(updateArrItem({ name: type, val: inputValue }));
};

Why This Works:

  • The updateArrItem reducer replicates the exact logic from your useState updater: it checks if the item exists, updates it if it does, adds it if it doesn't, and removes it if the input is cleared.
  • Redux Toolkit's Immer integration lets you write "mutating" code that gets converted to immutable updates under the hood, so you don't have to manually spread arrays like you do with vanilla React state.
  • You no longer need to sync local state with Redux—your component can directly read the state from Redux and dispatch actions to update it.

What Was Wrong Before:

  • Your original setArr reducer tried to spread action.payload into the array, but action.payload was a single object (not an iterable array), hence the TypeError: action.payload is not iterable.
  • When you changed it to state.arr = action.payload, you were overwriting the entire array with a single object each time, which is why only one item was stored.

内容的提问来源于stack exchange,提问作者Mohammed Bekele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:40:51