子组件不会重新渲染

时间:2019-09-29 08:13:05

标签: reactjs react-redux

我正在与redux一起使用,我有一个待办事项清单。 我有一个类似于容器的“ 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);

我注意到,如果我确实在child comp中传递了mapStateToProps,它将重新呈现,如下所示:

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

我了解,如果我在子级中使用mapStateToProps,它将重新渲染,但是我不需要子级中的状态直接提供任何信息,父级会这样做。 这是有道理的,但是我的待办事项在状态下存储在Array中,并且正如您在父组件中看到的那样,我正在映射它们,所以我无法将特定的待办事项从该数组映射到组件props(我如何区分数组中的每个元素都可以映射到prop?)。

我很困惑。 当状态或道具更改时,我读到该组件会重新渲染。在子组件内部,道具会发生变化,因为父组件会重新渲染并再次迭代待办事项,并使用新的道具返回组件。 也许这不是将待办事项传递给组件的方法,但我仍然不了解如何更改道具和不调用render()。

非常感谢您!

编辑1:

我将checkTodo动作连接到父组件,并通过props传递了该函数,并且效果很好。 仍然我不明白为什么子组件没有用之前的代码重新呈现...

编辑2:

实际上我只是在撒谎,这是行不通的。我忘了删除我曾说过的mapStateToProps,所以我回到了平方。

编辑3:

通过调用forceUpdate()解决。仍然不明白为什么会这样。

0 个答案:

没有答案