Обновление свойства состояния в componentDidMount не отражается с помощью реагирующей таблицы

Обновление значения свойства состояния data в методе компонента реакции componentDidMount без обновления данных таблицы реакции.

вызов 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>
    );
  }
}

person ida    schedule 03.03.2019    source источник
comment
он печатает данные в вашей консоли?   -  person Shadab Ahmed    schedule 03.03.2019
comment
Да, он печатает данные.   -  person ida    schedule 03.03.2019
comment
как указал @dacre, причина верна. вы также можете использовать getDerivedStateFromProps в своем компоненте T и обновить состояние на основе реквизитов, которые вызовут повторную визуализацию для него.   -  person Shadab Ahmed    schedule 03.03.2019


Ответы (2)


Не похоже, что есть что-то, что вызовет рендеринг вашего компонента T помимо начального рендеринга пустого массива data:[], переданного начальным состоянием компонентов <App/>.

Состояние для самого T инициализируется начальными данными пропса, переданными в <T> в первом цикле рендеринга <App/>. Поскольку реквизит data изначально является пустым массивом (на основе поля начального состояния data: [] в <App/>), это приведет к тому, что таблица будет казаться пустой. Однако нет ничего, что запускало бы компонент <T> для обновления (повторного рендеринга) после первого рендеринга, поскольку T передает данные в <ReactTable> из своего собственного внутреннего состояния (которое никогда не обновляется).

Рассмотрите возможность пересмотра метода render() компонента T, чтобы он отображал <ReactTable/> напрямую через свойство data, переданное в <T>, а не через внутреннее состояние, выполнив следующие действия:

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>
    );
  }
}
person Dacre Denny    schedule 03.03.2019
comment
Добавление методов componentDidMount и componentDidUpdate в T.js также работает. - person ida; 03.03.2019

Добавление методов 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>
    );
  }
}
person ida    schedule 03.03.2019