【问题标题】:reactjs child element not re-render while parent doesreactjs子元素不重新渲染而父元素
【发布时间】:2018-08-05 15:03:30
【问题描述】:

我在我的 reactjs 项目中得到了以下代码。

这背后的想法是点击按钮,然后editTodoStatus函数会改变lists对象的完整状态。

  import { Button } from 'reactstrap';
  import React, { Component } from "react";
  import ReactDOM from "react-dom";
  import * as TodoActions from "../actions/TodoActions";
  class List extends Component {
    constructor() {
      super();
      this.state = {
        lists:TodoStore.getTodos()
      };
    }
    editTodoStatus(event){
       const id = event.target.parentNode.dataset.id;
       TodoActions.editTodoStatus(id);
    }

    componentWillMount(){
      TodoStore.on("create", this.getStoreData.bind(this));
      TodoStore.on("edit", this.getStoreData.bind(this));
    }

    getStoreData(){
      this.setState({
        lists: TodoStore.getTodos()
      });
    }

    return(
     <div>    
     { 
        this.state.lists.map(
           function(todo){
              if (todo.complete){
                complete = <Button color="info"><i className="fa fa-check" /></Button>;
              }else{
                complete = <Button color="danger" onClick = {this.editTodoStatus.bind(this)} ><i className="fa fa-times" /></Button>;
              }
              return (
                  <li key = {todo.id} >
                    {complete}
                  </li>
              );
           }.bind(this)
        );
     }
     </div>
   );
}
export default List;

但是,该应用将仅重新呈现 Button 元素并忽略其中的 &lt;i&gt; 元素,这意味着 &lt;i&gt; 保持不变。

但如果我删除 &lt;Button&gt; 元素,&lt;i&gt; 将按预期重新渲染。

我不确定这背后的原因和问题的解决方案。

这是我的项目的链接。 https://johnhckuo.github.io/Todo-List/

如果你按下红色按钮使这个待办事项“完成”,你会看到问题(按钮的颜色改变了,但里面的图标没有改变)

我非常感谢任何建议。

【问题讨论】:

  • 您没有在映射函数中返回任何内容
  • 用你当前的代码什么都不应该呈现,你在哪里使用complete ?
  • @MayankShukla 抱歉,我已经简化了代码,忘记添加返回部分:p 已编辑!
  • @Axnyff 对不起,我忘记添加返回部分>
  • 您正在为button 使用任何库,或者您已经定义了该组件?

标签: javascript reactjs font-awesome


【解决方案1】:

很有可能 Button 的属性没有被更改,因此 React 认为没有理由更新 child。尝试使用更直接的语法,同时显式更改 Button 的属性:

renderItem = (id, complete) => {
  return <li key={id}>
    <Button onClick={complete && this.editTodoStatus} color={`${complete ? 'info' : 'danger' }`}>
      <i className={`fa ${complete ? 'fa-check' : 'fa-times'}`}
    </Button>
  </li>;
};

render() {
  const { lists } = this.state;

  return ( 
    <div>
     { lists.map(todo => this.renderItem(todo.id, todo.complete)) }
    </div>
  );
}

另一个有用的技巧是使用 React Fragment 代替无用的 div 父级:

 import React, { Fragment } from 'react';

 //...
 render() {
   return (
     <Fragment>
        //...same code as before, without useless div
     </Fragment>
   );

 } 

调试 editTodoStatus 方法以查看这是否有效地触发了更改。 希望有帮助

【讨论】:

  • 您好,非常感谢您的建议! :) 但是按钮实际上可以重新渲染,除了它的子元素&lt;i&gt;
  • 我已经尝试过您明确更改 Button 属性的方法。但结果还是一样。但是,如果我用一些纯文本替换 &lt;i&gt; 标记,结果就可以正常工作!
猜你喜欢
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
  • 2022-01-02
相关资源
最近更新 更多