Какой компонент жизненного цикла реакции использовать для обновления состояния после поста axios

Я столкнулся с проблемой при настройке состояния после публикации 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;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
460
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Хм... Ваш конструктор не вызывает реквизиты в своем объявлении или 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, если только состояние/реквизиты не отличаются.

это не работает, как я написал, реакция игнорирует функцию componentWillRecieveProps.

randal 05.06.2019 05:34

Извиняюсь! Я неправильно понял проблему, с которой вы столкнулись. Вы должны использовать componentDidUpdate вместо componentWillReceiveProps, я обновил свой ответ, чтобы отразить это. Надеюсь, поможет!

helloitsjoe 05.06.2019 06:07

спасибо за объяснение, это то, что я ищу.

randal 05.06.2019 06:26

о да, это должно быть nextProps в первом аргументе.

randal 05.06.2019 06:28

Ничего страшного, рад, что помогло! Согласно документам React, это prevProps: reactjs.org/docs/react-component.html#componentdidupdate.

helloitsjoe 05.06.2019 13:57

Другие вопросы по теме