ReactJS - Как я могу правильно отобразить контент, который создается в родительском компоненте и передается дочернему компоненту? - PullRequest
0 голосов
/ 29 июня 2019

Кажется, я не могу отобразить имена моих столбцов в CarTable.tsx, когда массив упорядоченных строк передается в качестве опоры этому компоненту.Я знаю, что это какое-то странное асинхронное программирование.Кроме того, когда я нажимаю кнопку, порядок имен столбцов должен меняться, и это изменение должно отражаться в повторном рендеринге.

Я не могу обернуться вокруг него.Я думал, что асинхронные вещи, такие как setState () должны идти внутри ловушки жизненного цикла, такой как ComponentDidMount () (предложено коллегой).

Также, когда родительский компонент (App.tsx) меняет состояние и это состояние передаетсяв качестве опоры для дочернего компонента (CarTable.tsx), разве CarTable не должен перерисовываться через виртуальный DOM, обнаруживающий изменение?

Я пытался использовать ComponentDidMount () и ComponentWillMount (), чтобы установитьгосударство.

Вот код компонента приложения.

import React from 'react';
import './App.css';
import { Car } from './Models/Car';
import CarTable from './CarTable';

class App extends React.Component<any, any> {

  constructor(props: any) {
    super(props);

    this.state = {
      cars: [],
      ordering: []
    }

    this.changeColumnOrder = this.changeColumnOrder.bind(this);
  }

  componentDidMount() {
    let order = [
      ["Model", "Make", "Year"], ["Model", "Year", "Make"], 
      ["Make", "Model", "Year"], ["Make", "Year", "Model"], 
      ["Year", "Model", "Make"], ["Year", "Make", "Model"]
    ];

    let random = Math.floor(Math.random() * 5); // 0 - 5

    var models: string[] = ["Accord", "Civic", "Pathfinder"];
    var make: string = "Honda";
    var years: number[] = [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019];

    var cars: Car[] = [];

    for (let i = 0; i < 40; i++) {
      var randYear = Math.floor(Math.random() * 10); // 0 - 9
      var randModel = Math.floor(Math.random() * 3); // 0 - 2
      cars.push(new Car(models[randModel], make, years[randYear]));
    }

    console.log("Cars generated...");
    console.log(cars);

    this.setState({
      cars: cars,
      ordering: order[random]
    });
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1>Car Table</h1>
          <button onClick={this.changeColumnOrder} className="columnButton">Change Column Order</button>
          <CarTable cars={this.state.cars} order={this.state.ordering}></CarTable>
        </header>
      </div>
    );
  }

  // Method for changing the column order of the contents in the car table. 
  changeColumnOrder() {

    let order = [
      ["Model", "Make", "Year"], ["Model", "Year", "Make"], 
      ["Make", "Model", "Year"], ["Make", "Year", "Model"], 
      ["Year", "Model", "Make"], ["Year", "Make", "Model"]
    ];

    let random = Math.floor(Math.random() * 5); // 0 - 5

    console.log("Testing random order");
    console.log(order[random]);

    this.setState({
      ordering: order
    });

    console.log("Testing after set state.");
    console.log(order[random]);
    this.forceUpdate();
  }
}

export default App;

Вот код компонента CarTable.

import React from 'react';
import './App.css';
import { Car } from './Models/Car';

export default class CarTable extends React.Component<any, any> {

    constructor(props: any) {
        super(props);

        this.state = {
            cars: [],
            columnOrder: []
        }
    }

    componentWillMount(){
        this.setState({
            cars: this.props.cars,
            columnOrder: this.props.order
        });

        console.log("In CarTable.tsx, component did mount");
        console.log(this.state.columnOrder);
    }

    render() {
        return(
            <table id="carsTable">
                <thead>
                    <tr>
                    {this.state.columnOrder.map((column: string, key: any) => {
                        console.log("in header...")
                        console.log({column});
                        return(<th key={column}>{column}</th>)
                    })}
                    </tr>
                </thead>
                <tbody>
                    {this.state.cars.map((car: Car, key: any) => {
                        return(
                            <tr key={key}>
                                <td key={car.Make}>{car.Make}</td>
                                <td key={car.Model}>{car.Model}</td>
                                <td key={car.Year}>{car.Year}</td>
                            </tr>
                        )
                    })}
                </tbody>
            </table>
        )
    }
}

С кодом в текущем состоянии, в котором он находится, яЯ не могу отображать имена моих столбцов (Модель, Автомобиль, Год).

Ответы [ 2 ]

0 голосов
/ 29 июня 2019

Вы делаете это неправильно, вам не нужно состояние в дочернем компоненте. Просто используйте значения реквизита, как это

import React from 'react';
import './App.css';
import { Car } from './Models/Car';

export default class CarTable extends React.Component<any, any> {
    render() {
        return(
            <table id="carsTable">
                <thead>
                    <tr>
                    {this.props.order.map((column: string, key: any) => {
                        console.log("in header...")
                        console.log({column});
                        return(<th key={column}>{column}</th>)
                    })}
                    </tr>
                </thead>
                <tbody>
                    {this.props.cars.map((car: Car, key: any) => {
                        return(
                            <tr key={key}>
                                <td key={car.Make}>{car.Make}</td>
                                <td key={car.Model}>{car.Model}</td>
                                <td key={car.Year}>{car.Year}</td>
                            </tr>
                        )
                    })}
                </tbody>
            </table>
        )
    }
}
0 голосов
/ 29 июня 2019

В конструкторе CarTable удалите

this.setState({
    cars: this.props.cars,
    columnOrder: this.props.order
});

При рендеринге используйте this.props.cars и columnOrder вместо this.state.xxx

Вот и все

ВНа самом деле, вы можете удалить CarTable.constructor и CarTable.componentWillMount.Также удалите this.forceUpdate(); в родительском компоненте

...