提取对象时未调用componentDidUpdate

时间:2019-06-07 20:48:56

标签: reactjs

状态更改时,不会触发

componentDidUpdate。

几乎是用户界面,

用户输入图像标题值,然后上传图像。并且componentDidUpdate应该获取更新值

并像这样映射它

this.state.images.map( (img, i) => (     
    <Grid item sm={12} md={12} key={i} style={{ margin: '30px 0px'}}>
            <Paper>
                <Typography variant="h6" align="center">{img.image_title}</Typography>
            <Image image_url={img.img_url} />    
        </Paper>                              
    </Grid>
))  

但是componentDidUpdate甚至没有在componentDidUpdate方法中获取console.logs。

所以发生的事情是只有刷新后我才能看到更新的值,并且它会相应地映射。

我如何能够不刷新地正确更新状态,让我看到在images数组中传递的附加值?

反应

import React, { Component } from "react";
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import Paper from '@material-ui/core/Paper';
import ImageUploader from 'react-images-upload';
import Axios from '../Axios';
import Image from './Image';
class Dashboard extends Component{
    constructor(props){
        super();
        this.state = {
            image_url: 'http://www.conservewildlifenj.org/images/artmax_1001.jpg', 
            images: {}, 
            description:'',
            upload:false,
        }
    }
    handleUpload =  file =>  {
        const data = new FormData()
        const image = file[0]
        console.log(this.state.description)
        // data.append('ourImage', this.state.description)
        data.append('ourImage',image, this.state.description )
        Axios.post('/images/upload', data).then((response) => {
            console.log(response);
            this.setState({
                image_url:response.data.img_url,
                description:response.data.image_title
                // images: [...this.state.images, this.state.image_url ]
            })
        });
        this.props.history.push('/dashboard')
        console.log(this.state.image_url);
    }
    handleChange = (e) => {
        // e.preventDefault();
        this.setState({
            [e.target.name]: e.target.value
        })
        // console.log(this.state.description)
    }
    fileOnchange = (file) => {
        this.setState({
            [file[0].target.name]: file[0].target.value
        })
    }
    componentWillMount(){
        Axios.get('/images/uploads').then( (response) => {
            // let img;
            // let imgTitle;
            // Object.keys(response.data).forEach( (key) => {
            //     img = response.data[key].img_url
            //     imgTitle = response.data[key].image_title
            //     console.log(response.data);
            //     // console.log(key, img);


            //     console.log(this.state.images);
            // });

            this.setState({
                images: response.data
            })
        })


    }
    componentDidUpdate(nextProps, prevState) {
        if (this.state.image_url !== prevState.image_url) {
                console.log(nextProps.images); // doesnt fetch console log
                console.log(prevState.images); // doesnt fetch console log
                this.setState({
                    images: [ this.state.image_url, this.state.description, this.state.images]
                });
        }

        // console.log(this.state.images); 
    }
    onUploadClick = (e) => {
        e.preventDefault();
        this.setState({
            upload: !this.state.upload
        })
    }
    render(){
        const uploader = ( 
            <ImageUploader
                withIcon={true}
                withPreview={true}
                onChange={this.handleUpload}
                singleImage={true}
                buttonText='Upload an image'
                imgExtension={['.jpg', '.gif', '.png', '.gif']}
                maxFileSize={5242880}
            />
        )
        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>
                        <Button onClick={this.onUploadClick} variant="outlined" component="span" color="primary">
                            {/* toggle between Upload or Close
                                Will be upload by default, else if upload is clicked, close will show.
                            */}
                            {!this.state.upload ? "Upload": "Close"}
                        </Button>
                        {this.state.upload ? (
                            <div>
                             <TextField
                                 id="outlined-name"
                                 label="Image Title"
                                 name="description"
                                 type="text"
                                 fullWidth
                                 style={{ borderRadius: '0px'}}
                                 className=""
                                 value={this.state.description}
                                 onChange={this.handleChange}
                                 margin="normal"
                               />
                                <br></br>
                                <br></br>
                              {uploader}
                            </div>
                        ):(
                            null
                        )}
                    {this.state.images.length > 0 ? (
                        this.state.images.map( (img, i) => (     
                            <Grid item sm={12} md={12} key={i} style={{ margin: '30px 0px'}}>
                                 <Paper>
                                     <Typography variant="h6" align="center">{img.image_title}</Typography>
                                    <Image image_url={img.img_url} />    
                                </Paper>                              
                            </Grid>
                        ))
                    ) : (
                        <div>
                            <Grid item md={8}>
                                <Typography>No Images yet</Typography>
                            </Grid>
                        </div>
                    )}
                </Grid>
                {/* Images  */}
              </Grid>
            </div>
        )
    }
}
export default Dashboard;

console.log(响应)

{
  "data": {
    "img_url": "http://res.cloudinary.com/dq281hpqd/image/upload/v1559943872/uploads/iobe6hc1qkfqxnyww8ki.png",
    "image_title": "foo",
    "id": 66
  },
  "status": 200,
  "statusText": "OK",
  "headers": {
    "content-type": "application/json; charset=utf-8",
    "content-length": "135"
  },
  "config": {
    "transformRequest": {},
    "transformResponse": {},
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1,
    "headers": {
      "Accept": "application/json",
      "Authorization": "eyJhbGciOiJIUzI1N***********sgNUmaIg"
    },
    "method": "post",
    "baseURL": "http://localhost:3000",
    "withCredentials": true,
    "url": "http://localhost:3000/images/upload",
    "data": {}
  },
  "request": {}
}

1 个答案:

答案 0 :(得分:0)

有些关键问题可能导致非常讨厌的错误:

  • 在初始化状态下,您拥有images: {}(对象),后来,在componentDidUpdate函数中,您尝试将其设置为数组:[ this.state.image_url, this.state.description, this.state.images]。不要这样做,这很令人困惑。

  • 仅当您的if (this.state.image_url !== prevState.image_url)承诺成功解决后,Axios.post的条件才会触发。您能否分享console.log(response);的结果?否则,将永远不会被触发,至少基于此片段

更新: 我已经找到了真正的原因,为什么看不到图片(或者您可能会看到损坏的图片):

  1. 上传功能应扩展现有的图像阵列。我只是略微改编了Axios.post函数,以便能够在我这一边对其进行编译,但是您明白了这一点:
handleUpload =  file =>  {
    const data = new FormData()
    const image = file[0]
    console.log(this.state.description)
    // data.append('ourImage', this.state.description)
    data.append('ourImage',image, this.state.description )

    const axiosPost = new Promise(res => {
      setTimeout(() => res({
        data: {
          image_url: "newURL",
          image_title: "newTitle",
          description: 'a description'
        }
      }), 2000);
    });

    axiosPost.then(response => {
      const { image_url, description } = response.data;
      this.setState({
        image_url,
        description,
        images: [...this.state.images, response.data ]
      })
    });
    // this.props.history.push('/dashboard')
    console.log(this.state.image_url);
  }
  1. 您要重新声明images变量,并在每个componentDidUpdate上添加3个元素的新数组,这完全没有任何意义。您能否解释一下您在这个生命周期中真正想要实现的目标?因为您所需的一切都发生在handleUpload函数(状态更新)中