如何在React native redux的reducer中向数组添加元素?

cod*_*z18 116 react-native redux react-redux

如何arr[]在reducer中的redux状态数组中添加元素?我这样做 -

import {ADD_ITEM} from '../Actions/UserActions'
const initialUserState = {
    arr:[]
}

export default function userState(state = initialUserState, action)
{
    console.log(arr);
    switch (action.type)
    {
        case ADD_ITEM: 
            return { 
                      ...state,
                      arr: state.arr.push([action.newItem])
                   }

        default:
            return state
    }
}
Run Code Online (Sandbox Code Playgroud)

Yad*_*ran 306

将项添加到数组而没有变异的两个不同选项

case ADD_ITEM :
    return { 
        ...state,
        arr: [...state.arr, action.newItem]
    }
Run Code Online (Sandbox Code Playgroud)

要么

case ADD_ITEM :
    return { 
        ...state,
        arr: state.arr.concat(action.newItem)
    }
Run Code Online (Sandbox Code Playgroud)

  • @sapht如果你在ES6中编写代码,那么首选的是更容易阅读和优雅的IMO. (15认同)
  • 哪一个应该被认为是更可取的? (2认同)
  • 另外,第一个不是纯净的,第二个不是纯净的。来自Redux的文档:“非常重要的一点是,Reducer保持纯净。在reducer内绝不应该做的事情:1.更改其参数; 2.执行副作用,如API调用和路由转换; 3.调用非纯函数,例如Date.now()或Math.random()。” (2认同)
  • @CharmingRobot 第二个函数究竟是如何不纯的?1.它不会改变参数;2:没有任何副作用;3. Array.prototype.concat是一个纯函数; (2认同)
  • @CharmingRobot concat() 不会改变原始数组。 (2认同)

mar*_*oyo 21

push不会返回数组,而是返回它的长度(docs),所以你要做的就是用它的长度替换数组,丢失对它的唯一引用.试试这个:

import {ADD_ITEM} from '../Actions/UserActions'
const initialUserState = {

    arr:[]
}

export default function userState(state = initialUserState, action){
     console.log(arr);
     switch (action.type){
        case ADD_ITEM :
          return { 
             ...state,
             arr:[...state.arr, action.newItem]
        }

        default:return state
     }
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要`Object.assign`?它用于对象,本质上是同一件事。如果您有`arr:[... state.arr,action.newItem]`,则可以使用`obj:Object.assign({},state.obj,action.newItem`',前提是`obj`和`newItem`是对象。如果要对整个状态执行此操作,则可以执行Object.assign({},state,{arr:[..state.arr,action.newItem]}))。 (2认同)

phr*_*hry 14

由于这个问题得到了很多曝光:

如果您正在寻找这个问题的答案,那么您很可能正在遵循一个非常过时的 Redux 教程

官方建议(自 2019 年起)是使用官方 Redux Toolkit 编写现代 Redux 代码

除此之外,这将消除字符串操作常量并为您生成操作创建器。

createReducer它还将采用允许您在由或创建的Reducers中编写变异逻辑的方法createSlice,因此首先不需要在现代 Redux 的Reducers中编写不可变的代码。

请遵循官方 Redux 教程而不是第三方教程,以便始终获得有关 Redux 良好实践的最新信息,并且还将向您展示如何在不同的常见场景中使用 Redux Toolkit。

作为比较,在现代 Redux 中,这看起来像

const userSlice = createSlice({
  name: "user",
  initialState: {
    arr:[]
  },
  reducers: {
    // no ACTION_TYPES, this will internally create a type "user/addItem" that you will never use by hand. You will only see it in the devTools
    addItem(state, action) {
      // you can use mutable logic in createSlice reducers
      state.arr.push(action.payload)
    }
  }
})

// autogenerated action creators
export const { addItem } = slice.actions;

// and export the final reducer
export default slice.reducer;
Run Code Online (Sandbox Code Playgroud)


Joe*_*dee 8

如果需要插入数组中的特定位置,可以执行以下操作:

case ADD_ITEM :
    return { 
        ...state,
        arr: [
            ...state.arr.slice(0, action.pos),
            action.newItem,
            ...state.arr.slice(action.pos),
        ],
    }
Run Code Online (Sandbox Code Playgroud)

  • 我在这里偶然发现...尽管这个答案并不完全符合上面的问题。尽管如此,这正是我所寻找的。我正在寻找一种在数组中的特定索引中插入对象的方法。因此,我对答案投了赞成票。这非常有帮助,节省了我一些时间。谢谢! (2认同)

Vis*_*war 6

如果你想一个接一个地组合两个数组,那么你可以使用

//initial state
const initialState = {
   array: [],
}

...
case ADD_ARRAY :
    return { 
        ...state,
        array: [...state.array, ...action.newArr],
    }
//if array = [1,2,3,4]
//and newArr = [5,6,7]
//then updated array will be -> [1,2,3,4,5,6,7]
...
Run Code Online (Sandbox Code Playgroud)

此 Spread 运算符 (...) 迭代数组元素并存储在数组 [ ] 内或在数组中扩展元素,您只需使用“ for 循环”或任何其他循环即可执行此操作。