【问题标题】:State outside of ComponentDidMount does not appear to updateComponentDidMount 之外的状态似乎没有更新
【发布时间】:2020-10-02 10:25:16
【问题描述】:

您好,当我在 componentDidMount 方法之外的任何地方控制台记录我的组件的状态时,我发现我的状态充满了应该构建的空数组。我正在从 JSON 文件中获取数据,在 componentDidMount 中我可以看到状态更改为包含数据的数组,但是在其他任何地方,例如在我的渲染中,状态又回到了初始状态。

我想这个问题与组件的生命周期有关,所以很想了解发生了什么。

非常感谢!

import React from 'react';
import * as metrics from './metrics.json';

class MetricsTable extends React.Component {
    state = {
        coverages: [],
        speeds: [],
        qualities: [],
        responsiveness: [],
        securities: []
    }

    componentDidMount() {
        metrics[0].map((metric) => {
            
            if (metric.level_1 === 'Coverage') {
                let joined = this.state.coverages.splice(0, 0, metric)
                this.setState({ coverages: [...joined] })
            }

            if (metric.level_1 === 'Speed') {
                let joined = this.state.speeds.splice(0, 0, metric)
                this.setState({ speeds: [...joined] })
            }

            if (metric.level_1 === 'Quality') {
                let joined = this.state.qualities.splice(0, 0, metric)
                this.setState({ qualities: [...joined] })
            }

            if (metric.level_1 === 'Responsiveness') {
                let joined = this.state.responsiveness.splice(0, 0, metric)
                this.setState({ responsiveness: [...joined] })
            }
            
            if (metric.level_1 === 'Security') {
                let joined = this.state.securities.splice(0, 0, metric)
                this.setState({ securities: [...joined] })
            }
        })
    }
    
    render() {
        // when I console log on this line I get empty arrays for my state
        return (
            <div>
                // this following line displays my state with empty arrays
                <pre>{JSON.stringify(this.state)}</pre>
                hello
            </div>
        );
        
    }
    
}

export default MetricsTable;

第一张图片显示了带有数据数组的状态,这是控制台记录在 componentDidMount 中。

第二张图是我的渲染函数中this.state的控制台日志

【问题讨论】:

  • 这取决于您记录状态的确切位置,并且鉴于 this.setState 是异步的,您可能做得太早了。只需将其添加到您的 JSX:&lt;pre&gt;{JSON.stringify(this.state)}&lt;/pre&gt;,您就会看到状态变化很好(也不要使用 map 而不是 forEach)参见此处:stackoverflow.com/questions/41278385/…
  • 您能否展示或解释您在控制台日志记录的确切位置?
  • 嗨,克里斯,感谢您的回复,我在 componentDidMount 内的地图外进行控制台日志记录,该控制台显示了完全构建的数组。然后我在渲染中(就在返回语句上方)和空数组中进行控制台登录
  • 我已经在我的 jsx 中包含了该行,它仍然显示为一个空数组
  • 在渲染函数中控制台登录时会显示什么?

标签: javascript reactjs


【解决方案1】:

问题与这种代码有关:

let joined = this.state.coverages.splice(0, 0, metric)

请注意,joined 将始终是一个空数组。 splice 方法不返回新的结果数组。

你可以这样更新代码:

let joined = [...this.state.coverages, metric];

【讨论】:

    【解决方案2】:

    我用钩子重写了上面的代码。

    import React, { useState, useEffect } from "react";
    
    let metrics = [
      [
        [
          {
            level_1: "Coverage",
            name: "Coverage_1"
          }
        ],
        [
          {
            level_1: "Speed",
            name: "Speed_1"
          }
        ]
      ]
    ];
    const MetricsTable = () => {
      const [coverages, setcoverages] = useState([]);
      const [speeds, setspeeds] = useState([]);
      const [qualities, setqualities] = useState([]);
      const [responsiveness, setresponsiveness] = useState([]);
      const [securities, setsecurities] = useState([]);
    
      useEffect(() => {
        metrics[0].map((metric) => {
          console.log("metric = ", metric);
          if (metric[0].level_1 === "Coverage") {
            setcoverages(coverages.concat(metric));
          }
    
          if (metric[0].level_1 === "Speed") {
            setspeeds(speeds.concat(metric));
          }
    
          if (metric[0].level_1 === "Quality") {
            setqualities(qualities.concat(metric));
          }
    
          if (metric[0].level_1 === "Responsiveness") {
            setresponsiveness(responsiveness.concat(metric));
          }
    
          if (metric[0].level_1 === "Security") {
            setsecurities(securities.concat(metric));
          }
        });
      }, []);
    
      return (
        <div>
          coverages:{coverages.length}
          <br />
          speeds:{speeds.length}
          <br />
          qualities:{qualities.length}
          <br />
          responsiveness:{responsiveness.length}
          <br />
          securities :{securities.length}
        </div>
      );
    };
    
    export default MetricsTable;
    
    

    我认为指标是sample


    为什么要删除加入? 例如
    var fruits = [];
    
    var t= fruits.splice(0, 0, [{name:"Kiwi",id:"1"}]);
     console.log("t = ",t)
    

    t 为空。fruits 不为空且包含数据。

    【讨论】:

    • 我一开始是用钩子写的。谢谢你,但是当我在 useEffect 方法之后控制台日志时,状态仍然显示一个空数组
    • 我可以提供metrics.json的数据样本吗?
    • map中的metric是对象还是数组?
    • 指标是一个对象
    • 我可以提供metrics.json的数据样本吗?
    猜你喜欢
    • 2018-04-14
    • 2018-07-21
    • 1970-01-01
    • 2020-02-07
    • 2019-07-26
    • 2018-07-25
    • 2021-05-15
    • 2016-03-01
    • 2017-04-25
    相关资源
    最近更新 更多