在Axios发布信息后设置状态时,我遇到了挑战。
这样做
this.setState({
image_url:response.data.img_url,
// images: [...this.state.images, this.state.image_url ]
})
不会立即设置状态,因此在运行此代码时
this.state.images.map( (img, i) => (
<Grid item md={8} key={i}>
{/* <Image image_url={this.state.image_url}/> */}
<Image img_url={img} />
</Grid>
))
没有项目被更新,只是一个空数组。
因此,当用户上传文件后,我被迫使用类似于componentWillReceiveProps
的内容来更新状态。但是,我的尝试是忽略componentWillReceiveProps
方法。我无法在方法中看到console.log
使用componentDidUpdate
或componentWillUpdate
会出错
错误:已超过最大更新深度。当一个组件发生这种情况 反复呼叫
我该怎么办?
Dashboard.js
import React, { Component } from "react";
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import ImageUploader from 'react-images-upload';
import Axios from '../Axios';
import Image from './Image';
class Dashboard extends Component{
constructor(){
super()
this.state = {
image_url: 'http://www.conservewildlifenj.org/images/artmax_1001.jpg',
images: []
}
}
handleUpload = file => {
const data = new FormData()
const image = file[0]
data.append('ourImage',image)
data.append('name', image.name)
Axios.post('/images/upload', data).then((response) => {
console.log(response);
this.setState({
image_url:response.data.img_url,
// images: [...this.state.images, this.state.image_url ]
})
});
console.log(this.state.image_url);
}
componentWillReceiveProps(nextProps, prevState){
this.setState({
images:[nextProps.images, this.state.image_url ]
})
console.log(this.state.images);
// if(prevState.images && prevState.images.length){
// }
}
render(){
return(
<div>
<Grid container justify="center" spacing={16}>
<Grid item sm={8} md={6} style={{ margin: '40px 0px', padding: '0px 30px'}}>
<Typography align="center" variant="h6">
Welcome to the Dashboard
</Typography>
<ImageUploader
withIcon={true}
withPreview={true}
buttonText='Upload an image'
imgExtension={['.jpg', '.gif', '.png', '.gif']}
onChange={this.handleUpload}
maxFileSize={5242880}
/>
{this.state.images.length > 0 ? (
this.state.images.map( (img, i) => (
<Grid item md={8} key={i}>
{/* <Image image_url={this.state.image_url}/> */}
<Image image_url={img} />
</Grid>
))
) : (
<div>
<Grid item md={8}>
<Typography>No Images yet</Typography>
</Grid>
</div>
)}
</Grid>
{/* Images */}
</Grid>
</div>
)
}
}
export default Dashboard;
答案 0 :(得分:1)
您应该使用componentDidUpdate
而不是componentWillReceiveProps
。由于setState
的调用,道具不会改变,因此componentWillReceiveProps
不会被调用。
为了避免无限循环,您应该比较当前状态和先前状态中的image_url
,并且只有在它们不同时才调用setState
:
componentDidUpdate(prevProps, prevState) {
if (this.state.image_url !== prevState.image_url) {
this.setState({
images: [nextProps.images, this.state.image_url]
});
}
}
...
原因是调用setState
会触发重新渲染,再次渲染componentDidUpdate
,再次调用setState
,依此类推...因此您需要将其短路除非状态/道具不同,否则不呼叫setState
。
答案 1 :(得分:0)
嗯...您的构造函数不会在其声明或超级中调用props。这可能就是为什么它忽略componentWillReceiveProps的原因。