【问题标题】:Updating state property in componentDidMount not reflecting with react-table更新 componentDidMount 中的 state 属性未反映在 react-table 中
【发布时间】:2019-07-24 17:49:55
【问题描述】:

更新 react 组件方法 componentDidMount 中的 state 属性 data 值,而不是更新 react-table 数据。

在构造函数中调用 getData 可以正常工作。

App.js

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      data: []
    };
  }

  getData() {
    var MOUNTAINS = [
      {name: "Kilimanjaro", height: 5895, country: "Tanzania"},
      {name: "Everest", height: 8848, country: "Nepal"},
      {name: "Mount Fuji", height: 3776, country: "Japan"},
      {name: "Mont Blanc", height: 4808, country: "Italy/France"},
      {name: "Vaalserberg", height: 323, country: "Netherlands"},
      {name: "Denali", height: 6168, country: "United States"},
      {name: "Popocatepetl", height: 5465, country: "Mexico"}
    ];
    return MOUNTAINS;
  }

  componentDidMount() {
    this.setState({ data : this.getData()}, () => {
      console.table(this.state.data);
    });
  }


  render() {

    const { data } = this.state;
    return <T data={data} />;
  }
}

T.js

export default class T extends Component {
  constructor(props) {
    super(props);
    debugger;
    this.state = {
      data: props.data
    };
  }
  render() {
    return (
      <div>
        <ReactTable
          data={this.state.data}
          columns={[{
                  Header: "Name",
                  accessor: "name"
                },{
                  Header: "Height",
                  accessor: "height"
                },{
                  Header: "Country",
                  accessor: "country"
                }]}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        <br />
      </div>
    );
  }
}

【问题讨论】:

  • 它会在您的控制台中打印数据吗?
  • 是的,它打印数据。
  • 正如@dacre 所指出的,原因是正确的。您还可以在 T 组件中使用 getDerivedStateFromProps 并根据将触发重新渲染的道具更新状态。

标签: reactjs react-table


【解决方案1】:

除了&lt;App/&gt; 组件初始状态传递的空数组data:[] 的初始渲染之外,似乎没有任何东西会调用您的T 组件的渲染。

T 本身的状态在&lt;App/&gt; 的第一个渲染周期中使用传递给&lt;T&gt; 的初始道具数据进行初始化。因为prop data 最初是一个空数组(基于&lt;App/&gt; 中的初始状态字段data: []),这将导致表格显示为空。然而,除了第一次渲染之外,没有什么可以触发 &lt;T&gt; 组件更新(重新渲染),看到 T 从它自己的内部状态(永远不会更新)将数据传递给 &lt;ReactTable&gt;

考虑修改T 组件的render() 方法,使其直接通过传递给datadata 属性呈现&lt;ReactTable/&gt;,而不是通过执行以下操作通过内部状态:

export default class T extends Component {

  /*
  The changes below make this redundant

  constructor(props) {
    super(props);
    debugger;
    this.state = {
      data: props.data
    };
  }
  */

  render() {
    /* Extract data prop to local variable for subsequent use */
    const data = this.props.data;

    /* If no data prop has been provided, or is of unexpected type, 
       render a "no data" message instead. I've included this to
       illustrate this as a method to handle no or incorrect data 
       for the prop */
    if(!Array.isArray(data)) {
        return (<div>No data to display</div>)
    }

    /* Assume the data prop is of correct type, etc, so now render
    the <ReactTable> with data provided directly from prop rather
    than T's internal state */
    return (
      <div>
        <ReactTable
          data={data}
          columns={[{
                  Header: "Name",
                  accessor: "name"
                },{
                  Header: "Height",
                  accessor: "height"
                },{
                  Header: "Country",
                  accessor: "country"
                }]}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        <br />
      </div>
    );
  }
}

【讨论】:

  • 向 T.js 添加 componentDidMountcomponentDidUpdate 方法也可以工作。
【解决方案2】:

添加componentDidMount & componentDidUpdate 方法更新表数据。

import React, { Component } from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";

export default class T extends Component {
  constructor(props) {
    super(props);
    debugger;
    this.state = {
      data: props.data
    };
  }

  componentDidMount() {
    this.setState({
      data: this.props.data,
    });
  }

  componentDidUpdate(prevProps){
    if (prevProps !== this.props) {
      this.setState({
        data: this.props.data,
      });
    }
  }

  render() {

    return (
      <div>
        <ReactTable
          data={this.state.data}
          columns={[{
                  Header: "Name",
                  accessor: "name"
                },{
                  Header: "Height",
                  accessor: "height"
                },{
                  Header: "Country",
                  accessor: "country"
                }]}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        <br />
      </div>
    );
  }
}

【讨论】:

    猜你喜欢
    • 2021-01-06
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2020-05-18
    • 2014-04-27
    • 2021-10-19
    相关资源
    最近更新 更多