Filter会删除Redux存储中的所有状态

时间:2018-04-03 07:39:54

标签: reactjs redux react-redux

我对使用reducers案例DELETE_TODO的Redux iteams商店的过滤器有一点问题。

因此当我尝试删除待办事项列表中的一些元素时会发生问题。删除是有效的,但是每次单击某个单独的元素以删除它,整个待办事项列表就不见了。我不明白为什么。

我做了几个测试,以了解问题所在。我得到了什么:

  1. action工作正常,因为value通常来自reducers。过滤工作。
  2. 当应用程序中的列表被删除并且我尝试添加其他一些待办事项时,应用程序开始崩溃并显示错误 - TypeError: Cannot read property 'todos' of undefined
  3. 请尽快帮助别人,因为我已经空了...... :(

    / * REDUCERS * /

        import { combineReducers } from 'redux'
        import { ADD_TODO, ADDED_BUTTON, TOGGLE_BUTTON, EDIT_TODO, DELETE_TODO, FILTER_TODO_UP, FILTER_TODO_DOWN } from '../Variables/Variables'
    
        const initialState = {
        iteams: [{
            todos:[],
            buttons:[]
        }]
        }
    
        function TodoApp(state, action) {
        if (typeof state === 'undefined') {
            return initialState;
        }
    
        switch (action.type) {
            case ADD_TODO:
                console.log('Reduce',action.text);
                return Object.assign({}, state, {
                    iteams: [{
                        todos: [
                            ...state.iteams[0].todos, 
                            {
                                id: action.id,
                                text: action.text,
                            }
                        ],
                        buttons: [
                            ...state.iteams[0].buttons, 
                            {
                                id: action.id,
                                text: action.text,
                                done: false
                            }
                        ]
                    }]
                });
            case DELETE_TODO:
                return Object.assign({}, {
                    iteams: state.iteams.filter(iteam => {
                        iteam.todos.id !== parseInt(action.id)
                    })
                });
            default: 
                return state;
        }
        }
    
    
    
        export default TodoApp
    

    / * ACTIONS * /

    import { ADD_TODO } from '../Variables/Variables'
    
    let nextTodoId = 0;
    
    function AddTodo(text) {
        console.log('Action', text);
        return {
            type: ADD_TODO,
            id: nextTodoId++,
            text,
            done: false
        }
    };
    
    function DeleteTodo(id) {
        return {
            type: DELETE_TODO,
            id
        }
    };
    
    export { AddTodo }
    

    / * CONTAINER * /

    import { connect } from 'react-redux';
    import TodoList from '../Components/TodoList/TodoList';
    import { DeleteTodo } from '../Actions/AddTodo'
    
    const mapStateToProps = state => ({
        iteams: state.iteams
    });
    
    const mapDispatchToProps = dispatch => ({
          todoFormDelete: todo => dispatch(DeleteTodo(todo))
    });
    
    export default connect(
        mapStateToProps, 
        mapDispatchToProps)(TodoList)
    

    / * COMPONENT * /

    import React, {Fragment} from 'react';
    import TodoIteam from '../TodoIteam/TodoIteam'
    import ButtonToggle from '../ButtonToggle/ButtonToggle'
    
    class TodoList extends React.Component {
    handleDelete = (e) => {
        let target = e.target;
        let closestDelete = target.closest('span');
        let closestEdit = target.closest('button');
    
        if (closestDelete) {
            let index = closestDelete.parentNode.getAttribute('index');
            console.log('index', index);
            this.props.todoFormDelete(index);
        } else { 
            return 
        }
    }
    
    render(props) {
        return ( 
            <Fragment>
                {console.log('Hi', this.props.store.getState().iteams)}
                <div onClick={this.handleDelete}>
                    {this.props.iteams.map((iteam, index) => {
                        return <TodoIteam key={index} {...iteam} />
                    })}
                </div>
            </Fragment>
        );
    }
    }
    
    export default TodoList;
    

2 个答案:

答案 0 :(得分:1)

我对你的initialState很困惑。我认为一定是这个

const initialState = {
  iteams: {
    todos:[],
    buttons:[]
  }
}

ADD_TODO

case ADD_TODO:
  return Object.assign({}, state, {
    iteams: {
      todos: [
        ...state.iteams.todos, //Change here
        {
          id: action.id,
          text: action.text,
        }
      ],
      buttons: [
        ...state.iteams.buttons, //Change here
        {
          id: action.id,
          text: action.text,
          done: false
        }
      ]
    }
  })

DELETE_TODO

case DELETE_TODO:
  return {
    iteams: {
      todos: state.iteams.todos.filter(iteam => iteam.id !== parseInt(action.id)),
      buttons: state.iteams.buttons.filter(button => button.id !== parseInt(action.id))
    }
  }

答案 1 :(得分:0)

为什么迭代是一个数组? (顺便说一下,你的意思不是'物品'吗?)
添加“待办事项”后,您可以将其添加到iteams[0].todos。 但是,当你过滤以删除'todo'时,你会通过iteams数组,而不是通过todos数组......

对我来说(除非我不明白你打算做什么)是状态应该是:

iteams: {
  todos:[],
  buttons:[]
}

当您删除某个项目时,您应该过滤iteams.todos数组,而不是iteams数组。