Дочерний компонент не будет повторно отображаться - PullRequest
0 голосов
/ 29 сентября 2019

Я использую реагировать с редуксом, и у меня есть список задач.У меня есть компонент 'Todos', который действует как контейнер, и компонент 'Todoitem', который содержит все задачи.Все работает нормально - редукторы изменяют состояние и обновляются с новыми данными, но дочерний компонент (он же компонент Todoitem) не будет перерисовываться.

Todos.js:

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import TodoItem from "./TodoItem";

class Todos extends Component {
  render() {
    return (
      <div className="Todos">
        <div className="todos_title"> {this.props.title} </div>
        {this.props.todos.map(todo => {
          console.log(todo); // this line prints updated data from state just fine!
          return <TodoItem todo={todo} key={todo.id}></TodoItem>;
        })}
      </div>
    );
  }
}

// PropTypes
Todos.propTypes = {
  todos: PropTypes.array.isRequired
};

const mapStateToProps = state => ({
  todos: state.todosReducer.todos
});

export default connect(mapStateToProps)(Todos);

TodoItem.js:

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { checkTodo } from "../actions/todosAction";

class TodoItem extends Component {
  onChange = (e, id) => {
    console.log(this.props.todo.completed.toString()); // this also prints fine the updated data
    this.props.checkTodo(id); // dispatches an action to the reducer to toggle the todo.completed with the right todo.id
  };

  render() {
    console.log('rendering'); // this is the problem - this line calls only in the first rendering, but not when state changes
    let { id, title, completed } = this.props.todo;
    return (
      <div className={completed ? "TodoItemDone" : "TodoItem"}>
        <p>
          <input
            className="todo_cb"
            type="checkbox"
            onChange={e => this.onChange(e, id)}
            checked={completed ? "checked" : ""}
          />
          {id}) {title}
        </p>
      </div>
    );
  }
}

// PropTypes
TodoItem.propTypes = {
  todo: PropTypes.object.isRequired
};

const mapDispatchToProps = dispatch => ({
  checkTodo: todo => dispatch(checkTodo(todo))
});

const mapStateToProps = state => ({});

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

Я заметил, что если я передаю mapStateToProps в дочернем компе, то это повторный рендеринг, например:

const mapStateToProps = state => ({
  some_prop: state
});

Я понимаю, еслиЯ использую mapStateToProps в потомке, который он перерисовывает, но мне ничего не нужно напрямую из состояния в потомке, родитель делает это.Это имеет некоторый смысл, но мои задачи хранятся в массиве в состоянии, и я сопоставляю их, как вы видите в родительском компоненте, поэтому я не могу отобразить конкретную задачу из этого массива в подпорки компонента (как я могу различитькаждый элемент в массиве сопоставить с подпоркой?).

Я очень запутался.Я читал, что компонент повторно рендерится, когда состояние или его реквизит меняются.Внутри дочернего компонента реквизиты действительно изменяются, потому что родительский объект рендерится повторно, и он повторяет задачи снова и возвращает компонент с новыми реквизитами.Может быть, это не способ передать задачи компонентам, но я до сих пор не понимаю, почему происходит изменение реквизита и не вызывается render ().

Большое спасибо!

Редактировать1:

Я подключил действие checkTodo к родительскому компоненту и передал функцию с помощью props, и она работает просто отлично.Тем не менее, я не понимаю, почему до того, как дочерний компонент не перерисовался с предыдущим кодом ...

Редактировать 2:

На самом деле я просто соврал, он не работает.Я забыл удалить mapStateToProps, который, как я сказал, сработал, поэтому я вернулся к исходной точке.

Редактировать 3:

Решено с помощью вызова forceUpdate ().До сих пор не могу понять, почему это произошло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...