【问题标题】:React setState function not reached thus not working未达到 React setState 功能,因此无法正常工作
【发布时间】:2020-09-04 11:09:31
【问题描述】:

我试图计算已完成的任务,我相信逻辑应该是正确的,但似乎 this.setState({}) 根本没有响应/到达,它没有对 this.state({}) 中的数据“qtySelected”做任何事情因为console.log('ts') 在控制台中没有结果。任何人都知道为什么,也许是一些反应生命周期问题?

export class Main extends Component {
    constructor(pros) {
        super(pros)
        this.state = {
            tasks: [
                {
                    id: 1,
                    content: "Sara's doctor and vaccine",
                    due: '2020-08-29',
                    completed: false
                },
                {
                    id: 2,
                    content: "Trash bags / facial masks / child allowance",
                    due: '2020-08-28',
                    completed: false
                },
                {
                    id: 3,
                    content: "Apply for Portugal nationality",
                    due: '2020-09-31',
                    completed: false
                },
                {
                    id: 4,
                    content: "My registeration card",
                    due: '2020-09-28',
                    completed: false
                },
                {
                    id: 5,
                    content: "contact ADEM",
                    due: '2020-12-31',
                    completed: false
                },
                {
                    id: 6,
                    content: "Pay loan",
                    due: '2020-09-03',
                    completed: true
                }
            ],
            qtySelected: 0
        }

    }


    componentDidMount() {    
        this.countSelected = () => {
            console.log('ts')
            let tasksCompleted = this.state.tasks.filter(task => {
                return task.completed === true
            })
            this.setState({
                qtySelected: tasksCompleted.length
            })
        }    
    }

    render() {
        return (
            <div>
                <table>
                    <tfoot>
                        <tr>
                            <td style={{ whiteSpace: "nowrap" }}>{this.state.qtySelected} selected</td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        )
    }
}

【问题讨论】:

    标签: reactjs setstate react-lifecycle


    【解决方案1】:

    您没有在任何地方调用this.countSelected 函数。无论哪种方式,您可以直接从当前状态计算的数据都不应该存储在该状态中。

    export class Main extends Component {
      constructor(props) {
        super(props);
        this.state = {
          tasks: [
            // ...
          ],
        };
      }
    
      render() {
        const selectedCount = this.state.tasks.filter((task) => task.completed).length;
        return (
          <div>
            <table>
              <tfoot>
                <tr>
                  <td style={{ whiteSpace: "nowrap" }}>{selectedCount} selected</td>
                </tr>
              </tfoot>
            </table>
          </div>
        );
      }
    }
    

    【讨论】:

    • 感谢您的解决方案,它奏效了。但是你说“不应该”,为什么?这只是一个不好的做法,但仍然有效,或者它只是错误并且不起作用(我尝试仍然像 Luke Storry 建议的那样保持“qtySelected”状态,但它仅在加载时有效,并且在我选中其他框时不会更新,是它是由我添加这个额外的新状态 qtySeleceted 引起的?)
    • 这只是一种不好的做法——它仍然可以工作,但每次你使用setState 时它都会重新渲染组件——如果你只是纯粹基于旧状态创建新状态,你不'不需要让它重新渲染两次 - 只需将计算值存储在一个变量中,就像在这个答案中一样
    【解决方案2】:

    您实际上并没有在 componentDidMount 中运行任何东西 - 您只是在定义一个新函数 this.countSelected

    当您使用以前的状态值更新状态时,还使用setState 的回调版本是best practise


    总而言之,您可以将其用作您的新 componentDidMount,它应该可以按预期工作:

    componentDidMount() {    
        this.setState(state => ({
            qtySelected: state.tasks.filter(task => task.completed).length
        }))
    }
    

    或者,您可能应该直接使用此计算值,而不是强制进行第二次重新渲染,因为它实际上不需要是单独的状态变量。

    <td style={{ whiteSpace: "nowrap" }}>
      {this.state.tasks.filter(task => task.completed).length} selected
    </td>
    

    【讨论】:

    • 感谢您的解释,但第一种方式仍然存在问题:它仅在您刚刚加载页面时起作用,然后如果您选中其他复选框,则数字不会更新并且停留在选择的“1”。第二个虽然没有问题。
    • 是的,这就是componentDidMount 的确切定义。它将在安装时运行一次。如果你想让它运行每个渲染,把它放在渲染函数中。
    【解决方案3】:

    没有执行 this.countSelected 函数。 所以删除该函数或使其外部到 componentDidMount 并从 componentDidMount 调用它。

    【讨论】:

      猜你喜欢
      • 2021-10-01
      • 2021-07-28
      • 2020-12-18
      • 2017-09-23
      • 1970-01-01
      • 2013-11-06
      • 2013-10-29
      • 1970-01-01
      相关资源
      最近更新 更多