调度动作后,Redux不会获取数组

时间:2019-06-24 21:04:11

标签: reactjs redux react-redux

我希望将UPLOAD_IMAGE中的数据附加到GET_IMAGES。无需重新渲染组件。换句话说,而不必刷新页面。

每当遵循img时,我都会遇到类型错误

  <Typography className={classes.imageTypographyTitle} variant="h4" align="center">{img.image_title}</Typography> 
               <Divider className={classes.imageDivider} variant="middle" />
               <Image image_url={img.img_url} />   
               <Typography variant="h6" align="center">{img.user.username}</Typography> 
               <Typography variant="h6" align="center">{moment(img.created_at).calendar()}</Typography> 
               ........                 
  

TypeError:无法读取未定义的属性“ image_title”

刷新后,我会看到新数据,并且可以添加数据,也可以看到更新后的阵列。仅当images数组为空时,才会发生类型错误。

我想将数据追加到空数组,并显示数据而无需重新渲染/刷新或任何类型错误。

我应该使用其他生命周期方法吗?因为componentWillMount不能被调用两次,只能被调用一次。因此,鉴于该数组为空,我是否应该使用shouldComponentUpdate之类的东西来获取初始数据?

数据结构,因为它们是数组中的现有数据。

0:{
  "id": 71,
  "image_title": "ii",
  "img_url": "https://*********",
  "created_at": "2019-06-24T02:36:48.359Z",
  "updated_at": "2019-06-24T02:36:48.359Z",
  "user_id": 1,
  "user": {
    "id": 1,
    "googleId": null,
    "username": "a******",
    "password": "**********",
    "email": "a********",
    "created_at": "2019-06-23T18:57:17.253Z",
    "updated_at": "2019-06-23T18:57:17.253Z"
  },
  "comments": []
}

减速器

import { GET_IMAGES, POST_COMMENT, DELETE_IMAGE, UPLOAD_IMAGE } from '../actions/types';

const initialState = {
    images:[],

}

export default  (state = initialState, action) => {
    switch (action.type) {
        case GET_IMAGES:
            console.log(action.data);
            return{
                ...state,
                images:action.data
            }
        case UPLOAD_IMAGE:
            const newState = {...state}
            const myImages = newState.images 
            // console.log(myImages); // empty array
            const newImage = action.newImage
            console.log(newImage[0]); // gets the new uploaded image. 

            return {
                images:[

                    {
                        id: newImage[0].id,
                        user:{
                            username:newImage[0].user.username
                        },
                        comments:{
                          comment_body: newImage[0].comments.comment_body  
                        },
                        image_title: newImage[0].image_title,
                        img_url: newImage[0].img_url,
                    },

                    myImages[0] // pass the previous images if array 
                                /// isn't empty

                ]   

            }

        default:
            return state;
    }
}

动作

// upload image 
export const uploadImage = data =>  {
   return (dispatch) => {
    Axios.post('/images/upload', data).then((response) => {
        const newImage = {...response.data}
        console.log(newImage);

        dispatch({type:UPLOAD_IMAGE, newImage})
        // history.push("/dashboard");
    });

   } 

}    
// get images
export const getImages = () => {
    return async (dispatch) => {
       const url =  await Axios.get('/images/uploads')
       const data = url.data;
        dispatch({ 
            type: GET_IMAGES,
            data
        })

    }
}

Dashboard.js

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 ImageUploader from 'react-images-upload';
import ImageContainer from "./ImageContainer"
import {connect} from 'react-redux';
import {getImages, deleteImage, uploadImage} from '../actions/imageActions';
import dashboardStyles from '../styles/dashboardStyles';
import {withStyles} from '@material-ui/core/styles';
import {compose} from 'redux';
class Dashboard extends Component{
    constructor(props){
        super(props);
        this.state = {
            image_url: '', 
            description:'',
            upload:false,
            isComment:false,
            comment_body:''
        }
    }
    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 )
        this.props.uploadImage(data);

        this.setState({
            description: ''
        })



    }
    handleChange = (e) => {
        // e.preventDefault();
        this.setState({
            [e.target.name]: e.target.value
        })
        // console.log(this.state.description)
    }
    componentDidMount(){
        this.props.getImages();
        console.log(this.props.image.images);
    }


      .........
      {image.images.length > 0 ? (
       image.images.map( (img, i) => (   
           <div key={i}>
               <ImageContainer img={img} deleteImg={() => this.deleteImg(img.id)}/>
           </div>      
       ))
      ) : (
          <div>
              <Grid item md={8}>
                  <Typography>No Images yet</Typography>
               </Grid>
          </div>
      )}


const mapStateToProps = (state) => ({
   image: state.image
})
const mapDispatchToProps = (dispatch) => ({
   getImages: () => dispatch(getImages()),
   uploadImage: (data) => dispatch(uploadImage(data))
})
export default compose(connect(mapStateToProps, mapDispatchToProps), withStyles(dashboardStyles))(Dashboard)

图像容器

  render(){
       const { img, deleteImg, classes } = this.props
       return(
           <Grid item sm={12} md={12} className={classes.imageGridItem}>
               <Paper className={classes.imageContainerPaper}>
         {/* // empty image_title */}
               <Typography className={classes.imageTypographyTitle} variant="h4" align="center">{img.image_title}</Typography> 
               <Divider className={classes.imageDivider} variant="middle" />
               <Image image_url={img.img_url} />   
               <Typography variant="h6" align="center">{img.user.username}</Typography> 
               <Typography variant="h6" align="center">{moment(img.created_at).calendar()}</Typography> 
               ........                       
        </Grid>        
      )
   }
}

2 个答案:

答案 0 :(得分:1)

您需要在新状态内散布现有图像阵列。

    case UPLOAD_IMAGE:
        const newState = {...state}
        const myImages = newState.images 
        // console.log(myImages); // empty array
        const newImage = action.newImage
        console.log(newImage[0]); // gets the new uploaded image. 

        return {
            images:[

                {
                    id: newImage[0].id,
                    user:{
                        username:newImage[0].user.username
                    },
                    comments:{
                      comment_body: newImage[0].comments.comment_body  
                    },
                    image_title: newImage[0].image_title,
                    img_url: newImage[0].img_url,
                },
                ...state.images

            ]   

        }

因此,您将拥有一个新状态,首先是新图像,然后是初始图像。

答案 1 :(得分:0)

修复。删除此行。

myImages[0] // pass