Я столкнулся с проблемой при настройке состояния после публикации 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.info в методе
Использование componentDidUpdate или componentWillUpdate приводит к ошибке
ERROR: Maximum update depth exceeded. This can happen when a component repeatedly calls
Что я должен делать ?
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.info(response);
this.setState({
image_url:response.data.img_url,
// images: [...this.state.images, this.state.image_url ]
})
});
console.info(this.state.image_url);
}
componentWillReceiveProps(nextProps, prevState){
this.setState({
images:[nextProps.images, this.state.image_url ]
})
console.info(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;





Хм... Ваш конструктор не вызывает реквизиты в своем объявлении или super. Возможно, поэтому он игнорирует componentWillReceiveProps.
Вы должны использовать 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, если только состояние/реквизиты не отличаются.
Извиняюсь! Я неправильно понял проблему, с которой вы столкнулись. Вы должны использовать componentDidUpdate вместо componentWillReceiveProps, я обновил свой ответ, чтобы отразить это. Надеюсь, поможет!
спасибо за объяснение, это то, что я ищу.
о да, это должно быть nextProps в первом аргументе.
Ничего страшного, рад, что помогло! Согласно документам React, это prevProps: reactjs.org/docs/react-component.html#componentdidupdate.
это не работает, как я написал, реакция игнорирует функцию componentWillRecieveProps.