【发布时间】:2019-06-19 20:50:59
【问题描述】:
我有一个 React 组件 (Albums),render() 方法根据其状态返回两个可能组件之一。其中一个组件 (AlbumsTable) 使用两个 props 参数调用,classes 和 albums。第二个 props 参数是由 ajax 在方法 (getData) 中使用 Axios 获得的数组,该方法更新 Albums 状态导致其重新渲染。
由于 Ajax 的异步性,Albums 会渲染两次,第一次使用 this.albums = [],第二次(由 getData() 状态更新引起)使用 this.albums 等于 ajax 的结果。
问题是我可以追踪到AlbumsTable.constructor() 仅被调用一次(Albums 第一次呈现),此时this.albums 等于[]。所以第二次Albums渲染,当this.albums等于ajax的结果时,这个内容不会作为props发送给AlbumsTable,导致ajax的结果永远不会显示。
这是我的组件的代码:
import React, { Component } from 'react';
import Cookies from 'js-cookie';
import axios from 'axios';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
const styles = theme => ({
root: {
width: '100%',
marginTop: theme.spacing.unit * 3,
overflowX: 'auto',
},
table: {
minWidth: 700,
},
});
class AlbumsTable extends Component {
constructor(props) {
super(props);
this.state = {
classes: props.classes,
}
if(props.albums === undefined){
this.albums = [];
} else {
this.albums = props.albums;
}
}
render() {
return (
<Paper className={this.state.classes.root}>
<Table className={this.state.classes.table}>
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell align="right">Name</TableCell>
<TableCell align="right">Photos</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.albums.map(album => {
return (
<TableRow key={album.id}>
<TableCell component="th" scope="row">
{album.name}
</TableCell>
<TableCell align="right">{"photos"}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</Paper>
);
}
}
class AlbumDetail extends Component {
render() {
return(<p>Album Detail Comming Soon...</p>);
}
}
class Albums extends Component {
constructor(props) {
super(props);
this.state = {
classes: props.classes,
mode: 'table',
albums: [],
};
this.albums = [];
this.getData();
}
getData() {
const axios = require('axios');
var userToken = Cookies.get('token');
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.get('http://127.0.0.1:8000/es/api/albums/',
{
headers: {
Authorization: userToken,
}
}
)
.then(function (response) {
console.log(response);
this.albums = response.data.results;
this.setState({albums: this.state.albums + 1});
}.bind(this))
.catch(function (error) {
console.log(error);
return(null);
})
}
setData(albums) {
this.setState({albums: albums});
}
render() {
if(this.state.mode === 'table'){
return (<AlbumsTable classes={this.state.classes} albums={this.albums} />);
} else {
return (<AlbumDetail />);
}
}
}
Albums.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Albums);
我想我错过或误解了有关组件渲染的一些内容。
【问题讨论】:
标签: javascript reactjs material-ui