【问题标题】:How to implement Reducer when store initial state is an Array?存储初始状态为数组时如何实现Reducer?
【发布时间】:2021-07-12 13:26:11
【问题描述】:

我正在尝试了解 React-Redux 基础知识,但我陷入了这种特殊情况:

我的代码操作:


let todoId = 1

export const ADDTODO = 'AddTodo'
export const REMOVETODO = 'RemoveTodo'
export const TOINPROGRESS = 'ToInProgress'
export const TODONE = 'ToDone'

export function addTodo(payload){
return{
   type: ADDTODO,
   payload:{
      status: 'Todo',
      id: todoId++,
      title: payload.title,
      date:payload.date,
      description:payload.description,
      place:payload.place     
        }                                
    }       
}

export function removeTodo(todoId){
    return{
        type: REMOVETODO,
        payload:todoId
    }
}

export function toInProgress(todoId){
    return{
        type: TOINPROGRESS,
        payload:todoId
    }
}

export function toDone(todoId){
    return{
        type: TODONE,
        payload:todoId
    }
}

我尝试减少代码:


import { addTodo, removeTodo, toInProgress, toDone } from '../actions';
const initialState = [];

const todos = (state = initialState, action) => {
  switch(action.type) {   
      case 'AddTodo':      
        return[
          ...state, {           
            date:action.payload.date,
            description:action.payload.description,
            id:action.payload.id,
            place:action.payload.place,
            status:action.payload.status,
            title:action.payload.title,
            
          }          
        ]  
       
 case 'RemoveTodo':
     console.log(state)            
     return {
         ...state,
         todos: state.todos.filter(todo => todo.id  !== action.id)
     }


               
 case 'ToInProgress':             
     state.map(todo =>(todo.id===action.id)?{...todo,status:"InProgress"}:todo)     
         
 case 'ToDone':    
     state.map(todo =>(todo.id===action.id)?{...todo,status:"Done"}:todo)
                  
 default: 
     return state
  }
}

tod​​os reducer 唯一的工作方法是 AddTodo,无法弄清楚 RemoveTodo、ToInProgress 和 ToDo 工作。 我在 RemoveTodo 收到一个 TypeError,上面写着“无法读取未定义的属性‘过滤器’”... 和 undefined 从另外两个方法返回。 你们能给我一些帮助吗?提前问候,请忘记我糟糕的语法和编码

【问题讨论】:

    标签: javascript reactjs redux state


    【解决方案1】:

    在您的情况下,状态是一个数组,因此 state.todos 将是未定义的。您可以使用类似的方法修复“RemoveTodo”案例

    case 'RemoveTodo':          
        return state.filter(todo => todo.id  !== action.payload)
    

    【讨论】:

    • 哇!这是一个快速的答案 Virtuoz! Tnx 帮了我很多。我试过你的代码,它没有删除对象。
    • @MartinGonzalez 我已经改变了答案,你能检查一下它现在是否有效吗?
    • 是的!我爱你m8!!!!你让我开心!非常感谢!!!
    【解决方案2】:

    在其他情况下您错过了return,并且您不需要分配action.payload 之外的每个属性,只需按原样传递即可,这就是它的外观

    const todos = (state = initialState, action) => {
        switch (action.type) {
          case "AddTodo":
            return [...state, action.payload];
          case "RemoveTodo":
            return state.filter((todo) => todo.id !== action.payload.id);
    
          case "ToInProgress":
            return state.map((todo) =>
              todo.id === action.payload.id
                ? { ...todo, status: "InProgress" }
                : todo
            );
    
          case "ToDone":
            return state.map((todo) =>
              todo.id === action.payload.id ? { ...todo, status: "Done" } : todo
            );
          default:
            return state;
        }
    };
    

    【讨论】:

    • Tnx 对你来说太 sathya! AddTodo 的改进效果很好!可悲的是 RemoveTodo 抛出 TypeError: Cannot read property 'filter' of undefined;并且 ToInProgress 和 ToDone 不会更新状态。
    • 我已经更新了代码,当时没有注意到其他的bug。你在比较中错过了action.payload.id
    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多