react-redux道具未更新

时间:2019-05-21 03:29:15

标签: reactjs redux react-redux

我正在尝试使用react-redux构建一个简单的 todo-app 。问题是当我尝试更新数据时,它不会在视图中更新。我的代码如下:

动作

export const listTodo = () => { type: actionTypes.LIST_TODO  }

export const updateTodo = ( payload, index ) => { type: actionTypes.UPDATE_TODO, payload, index }

减速器

const INITIAL_STATE = {
  all: [{
    name: 'init',
    status: false,
    lastUpdate: new Date().toISOString()
  }]
}

const listTodo = ( state, action ) =>  {...state, all: state.all }

const updateTodo = ( state, action ) => {
  const listTodo = {...state, all: state.all }; // init data

  // find data
  let todo = listTodo.all.filter( (todo, index) => index === action.index );
  // update data
  todo.name = action.payload.name;
  todo.status = action.payload.status;
  todo.lastUpdate = new Date().toISOString();

  listTodo.all[ action.index ] = todo;
  // return data
  return {
    ...state,
    all: listTodo.all
  }
}

export default ( state = INITIAL_STATE, action) => {
  switch( action.type ) {
    case LIST_TODO:
      return listTodo( state, action );
    case UPDATE_TODO:
      return updateTodo( state, action );
    default:
      return state;
  }
}

在下面的代码(Components/list.js中,我只是获取所有待办事项列表,然后使用ShowList打印所有列表。

Components / list.js

import ShowList from '../container/showList';

class TodoList extends Component {
   renderTodoList() {
     return this.props.all.map( (todo, index) => {
        return (
          <ShowList key={index} index={index} todo={todo} />
        );
      });
   }

  render() {
    return <ul> { this.renderTodoList() } </ul>
  }
}

const mapStateToProps = ( state ) => { all: state.todo.all };

export default connect( mapStateToProps ) ( TodoList );

在下面的代码(container/showList.js)中,待办事项列表使用<li />显示,并且还有一个checkbox,当用户单击复选框时,handleCheckbox将触发并会更新待办事项清单。我相信数据已正确更新,但并未在html上更新。在浏览器中,待办事项列表与以前相同。

容器/showList.js

class ShowList extends Component {

  handleCheckbox = (  ) => {
    const { todo, index } = this.props;
    todo.status = !todo.status;
    todo.lastUpdate = new Date().toISOString();
    this.props.onUpdateTodo( todo, index );
  }

  render() {
    const { todo, index } = this.props;
    return (
      <li> <input type="checkbox" onChange={ this.handleCheckbox } checked={todo.status} /> {todo.name} # {todo.status.toString()} # { todo.lastUpdate } </li>
    )
  }
}

const mapDispatchToProps = ( dispatch ) => onUpdateTodo: ( todo, index ) => dispatch( actions.updateTodo( todo, index ) )

export default connect(null, mapDispatchToProps) (ShowList);

如何解决此问题?预先感谢。

2 个答案:

答案 0 :(得分:1)

您的问题在这一行,

export const updateTodo = ( payload, index ) => { type: actionTypes.UPDATE_TODO, payload, index }

Redux Action仅使用2个参数,分别为typepayload

您在这里传递了3参数,这是错误的。删除您的index参数,您的操作将变成这样,

export const updateTodo = ( payload, index ) => { type: actionTypes.UPDATE_TODO, payload } //payload = your updated todo list

仅将更新的待办事项列表传递给您的操作,

this.props.onUpdateTodo( todo );

最后,仅在您的reducer中这样做

return Object.assign(state,action.todo) // This will merge your old state with updated todo list and eventually you will get a updated list.

查看更多Object.assign here

答案 1 :(得分:1)

您的问题出在您的reducers文件中。每当执行updateToDo()时,您实际上并没有在更新现有的待办事项,而只是将新属性添加到具有新更改的状态中。这将创建图层和属性图层,而无需实际更新第一层。而且,由于您的组件仅连接到第一层,因此它将永远无法获得更新状态。

我已经更新了一个代码框供您参考:https://codesandbox.io/s/lively-flower-mwh79

您可以将reducer更新为类似的代码,然后代码可以正常工作:

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case "LIST_TODO":
      return listTodo(state, action);
    case "UPDATE_TODO":
      return {
        ...state,
        all: state.all.map((todo, index) => {
          if (index == action.index) {
            return {
              ...todo,
              status: todo.status,
              lastUpdate: new Date().toISOString()
            };
          } else {
            return todo;
          }
        })
      };
    default:
      return state;
  }
};