【问题标题】:Reducer - add new element减速器 - 添加新元素
【发布时间】:2020-04-22 02:59:21
【问题描述】:

我有这家店:

const initialActors = {
    list: 'Actor\'s lists',
    actors: [
        {
            name: 'Angelina Jole',
            involved: true
        },
        {
            name: 'Bratt Pitt',
            involved: false
        },
    ]
}

我有一个 reducer 可以向我的商店添加一个新演员:

const actors = (state = initialActors, action) => {
    switch(action.type){
        case 'ADD_NEW':
            return {
                ...state.list,
                actors: [
                    ...state.actors,
                    action.name,
                    action.involved
                ]
            }
        default:
            return state
    }
}

我也有一个动作创建者,但这并不重要。我发送它并显示我的状态:

store.dispatch(addNew({name: "Hello", involved: true}) ); // I have this action creator
console.log(store.getState()

console.log 显示非常困难的对象,其字母如下:{0: "A", 1: "c"}。怎么了?

@编辑 我尝试将 ...state.list 更改为这样的状态列表:

const actors = (state = initialActors, action) => {
    switch(action.type){
        case 'ADD_NEW':
            return {
                state.list,
                actors: [
                    ...state.actors,
                    action.name,
                    action.involved
                ]
            }


        default:
            return state
    }
}

但我有这个错误:

解析错误:意外的令牌,应为“,” 如果我尝试修改演员数组,我会遇到类似的情况:

case 'ADD_NEW':
    return {
        ...state.list,
        actors: [
            ...state.actors,
            {
                action.name,
                action.involved
            }

        ]
    }

错误消息与此相同,但指向操作对象(action.name)。

【问题讨论】:

  • 添加了解决方案,请检查 :) 如果您需要任何进一步的说明,请告诉我
  • 你又在做 ....state.list,因为它是字符串,它会传播每个字符

标签: javascript reactjs redux store


【解决方案1】:

您所做的只是一个小错误,您需要添加为具有 2 个属性的对象,例如 [...state.actors, { action.name, action.involved }] 而不是您所做的。

来自Spread syntax 的文档:

Spread 语法允许在预期有零个或多个参数(对于函数调用)或元素(对于数组字面量)的地方扩展诸如数组表达式或字符串之类的可迭代对象,或者在需要扩展对象表达式的地方期望零个或多个键值对(用于对象文字)。

像这样:

const actors = (state = initialActors, action) => {
    switch(action.type){
        case 'ADD_NEW':
            return {
                ...state,
                actors: [
                    ...state.actors,
                    {  
                       name: action.name,
                       involved: action.involved
                    }
                ]
            }
        default:
            return state
    }
}

考虑以下几点:

var array = [
  {  
    name: 'someone',
    involved: false,
  }
];

console.log([...array, { name: 'hello', involved: true }]);

我希望这会有所帮助!

【讨论】:

    【解决方案2】:

    state.list 是一个字符串,你正在尝试传播它

    let a = 'name'
    let c = {...a}
    console.log(c)

    运行上面的代码sn-p这样你就可以理解了

    并且要添加新对象,您需要按如下方式更新减速器

                    ...state,
                    actors: [
                        ...state.actors,
                        {  
                           name: action.name,
                           involved: action.involved
                        }
                    ]
    

    所以上面的代码将传播状态中的所有现有属性,然后你传播所有当前的演员并添加一个新对象,如上所示

    更新

    因为你是作为

    store.dispatch(addNew({name: "Hello", involved: true}) );
    

    这里的payload是一个对象,所以你可以直接使用它

    所以在行动中,它将是具有两个道具的对象,一个是

    • 类型
    • 您发送的有效负载

                      ...state,
                      actors: [
                          ...state.actors,
                          action.payload
                      ]
      

    样品工作codesandbox

    【讨论】:

    • 但我试过这个state.list(没有...)我有错误:意外令牌(。),预期(,)
    • 你又在做 ....state.list,因为它是字符串,它会传播每个字符,在你有值的对象中,关键在哪里?
    • 尝试用上面的方法一模一样试试
    • 差不多。应用程序几乎没有问题。之前在 store 中创建的对象可以正常工作,但是新的 actor 有一个额外的对象。普通商店如下所示:actors: {name: 'Something', invloved: true}但您的代码创建的对象如下所示:actors: {name: {name: 'Something', involved: true}}
    • 让我检查一下,我会用示例 sn-p 代码尝试 mimc 那个,给我一些时间
    【解决方案3】:

    在你的减速器中,你错误地传播了state.list。因为它是一个字符串,所以你得到了所有的字母。你应该在那里传播state。因为,您想保留 state,而不是 actors 数组。这就是为什么您传播整个state 并保留list(如果有的话,与其他人一起)。

    另外,您添加的项目错误,它应该是一个对象。

    const actors = (state = initialActors, action) => {
      const { name, involved } = action;
    
      switch (action.type) {
        case "ADD_NEW":
          return {
            ...state,
            actors: [
              ...state.actors,
              {
                name,
                involved
              }
            ]
          };
        default:
          return state;
      }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      • 2020-03-04
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多