在发布axios后,生命周期组件有何反应来更新状态

时间:2019-06-05 02:22:45

标签: reactjs

在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

使用componentDidUpdatecomponentWillUpdate会出错

  

错误:已超过最大更新深度。当一个组件发生这种情况   反复呼叫

我该怎么办?

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;

2 个答案:

答案 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的原因。