Реакция-редукса не обновляется - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь создать простое приложение todo , используя react-redux. Проблема в том, что, когда я пытаюсь обновить данные, это не будет обновляться в поле зрения. Мой код указан ниже:

действия

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

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

1012 * Переходники *

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.

Компоненты / 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 ]

1 голос
/ 21 мая 2019

Ваша проблема была в вашем файле редукторов.Всякий раз, когда вы выполняли updateToDo(), вы фактически не обновляли существующие задачи, вы просто добавляли новое свойство в ваше состояние с новыми изменениями.Это создало слои и слои свойств без фактического обновления первого слоя.А поскольку ваши компоненты были подключены только к первому слою, он никогда не получит обновленное состояние.

Я обновил коды и поле для справки: https://codesandbox.io/s/lively-flower-mwh79

Вы можете обновить свойредукторы к чему-то вроде этого, и тогда ваш код работает совершенно нормально:

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;
  }
};
1 голос
/ 21 мая 2019

Ваша проблема в этой строке,

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

Redux Action будет принимать только 2 параметры, type и payload соответственно.

Здесь вы передаете 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 здесь

...