ReactJS - 如何正确呈现源自父组件并传递给子组件的内容?
ReactJS - How can I properly render content that originates in a parent component and is passed down to a child component?
当字符串顺序数组作为 prop 传递给此组件时,我似乎无法在 CarTable.tsx 中呈现我的列名称。我知道这是一些古怪的异步编程。此外,当我单击该按钮时,列名的顺序应该会发生变化,并且这种变化应该会反映在重新呈现中。
我无法理解它。我认为诸如 setState() 之类的异步内容应该放在诸如 ComponentDidMount() 之类的生命周期钩子中(同事建议)。
此外,当父组件 (App.tsx) 更改状态并且此状态作为 prop 传递给子组件 (CarTable.tsx) 时,CarTable 不应该通过虚拟重新渲染DOM 检测到变化?
我试过使用 ComponentDidMount() 和 ComponentWillMount() 来设置状态。
App组件代码如下
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>
)
}
}
使用当前状态下的代码,我根本无法呈现我的列名(型号、汽车、年份)。
在 CarTable 构造函数中,删除
this.setState({
cars: this.props.cars,
columnOrder: this.props.order
});
在渲染中,使用 this.props.cars 和 columnOrder 而不是 this.state.xxx
就是这样
实际上,您可以删除 CarTable.constructor
和 CarTable.componentWillMount
。
也去掉父组件this.forceUpdate();
中的
你做错了,你不需要子组件中的状态。只需按原样使用道具值
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>
)
}
}
当字符串顺序数组作为 prop 传递给此组件时,我似乎无法在 CarTable.tsx 中呈现我的列名称。我知道这是一些古怪的异步编程。此外,当我单击该按钮时,列名的顺序应该会发生变化,并且这种变化应该会反映在重新呈现中。
我无法理解它。我认为诸如 setState() 之类的异步内容应该放在诸如 ComponentDidMount() 之类的生命周期钩子中(同事建议)。
此外,当父组件 (App.tsx) 更改状态并且此状态作为 prop 传递给子组件 (CarTable.tsx) 时,CarTable 不应该通过虚拟重新渲染DOM 检测到变化?
我试过使用 ComponentDidMount() 和 ComponentWillMount() 来设置状态。
App组件代码如下
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>
)
}
}
使用当前状态下的代码,我根本无法呈现我的列名(型号、汽车、年份)。
在 CarTable 构造函数中,删除
this.setState({
cars: this.props.cars,
columnOrder: this.props.order
});
在渲染中,使用 this.props.cars 和 columnOrder 而不是 this.state.xxx
就是这样
实际上,您可以删除 CarTable.constructor
和 CarTable.componentWillMount
。
也去掉父组件this.forceUpdate();
中的
你做错了,你不需要子组件中的状态。只需按原样使用道具值
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>
)
}
}