提取新的阵列状态时反应类型错误

时间:2019-06-16 17:25:50

标签: reactjs redux

我正在尝试转换此代码

// this.setState({
//     description:'',   // resets title after upload
//     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,
//         created_at: new Date().toLocaleString().replace(',', ''),
//         updated_at: new Date().toLocaleString().replace(',', '')
//       },
//       ...this.state.images
//     ]
//   })

到redux减速器,这是我的尝试

Snippet Reducer

case UPLOAD_IMAGE:
const newState = {...state}
const myImages = newState.images // old images

const newImage = action.newImage
console.log(newImage); // gets the new uploaded image. 
return {
    images:[
        ...myImages,
        {
            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,
            created_at: new Date().toLocaleString().replace(',', ''),
            updated_at: new Date().toLocaleString().replace(',', '')
        }

    ]

}

截至目前,images []正在映射到仪表板组件中,并且它从redux reducer case GET_IMAGES:获取图像。上传图片时出现问题。我得到了错误

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

刷新后,新上传的图像将显示在地图迭代中。

我的猜测是旧图像包含在数组中,而新图像则位于我不知道的对象中的数组中。 / p>

旧图像数据结构(出于隐私目的进行了编辑)

[
  {
    "id": 217,
    "image_title": "ddddddf",
    "img_url": "http:/************579/uploads/lshndpj***g",
    "created_at": "2019-06-16T17:03:00.605Z",
    "updated_at": "2019-06-16T17:03:00.605Z",
    "user_id": 1,
    "user": {
      "id": 1,
      "googleId": null,
      "username": "E****",
      "password": *****$12$16UTTfIH6gXhnRMnBHFGHuHiI***EAGF3GCjO62",
      "email": "e****",
      "created_at": "2019-06-05T04:50:20.133Z",
      "updated_at": "2019-06-05T04:50:20.133Z"
    },
    "comments": []
  },

新上传的图片数据结构(出于隐私目的进行了修改)

{
  "0": {
    "id": 218,
    "image_title": "owl",
    "img_url": "http:/*********0705077/uploads******",
    "created_at": "2019-06-16T17:11:19.066Z",
    "updated_at": "2019-06-16T17:11:19.066Z",
    "user_id": 1,
    "user": {
      "id": 1,
      "googleId": null,
      "username": "BOB",
      "password": "$2b$12******"
      "created_at": "2019-06-05T04:50:20.133Z",
      "updated_at": "2019-06-05T04:50:20.133Z"
    },
    "comments": []
  },

也许数据结构存在差异,这就是为什么在遍历数组时会给我类型错误的原因。

完整代码

动作

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})    
   } 

}


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

减速器

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 // old images

            const newImage = action.newImage
            console.log(newImage); // gets the new uploaded image. 
            return {
                images:[
                    ...myImages,
                    {
                        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,
                        created_at: new Date().toLocaleString().replace(',', ''),
                        updated_at: new Date().toLocaleString().replace(',', '')
                    }

                ]

            }
        default:
            return state;
    }
}

Dashboard.js

const { image} = this.props

{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()),
   deleteImage : (id) => dispatch(deleteImage (id)),
   uploadImage: (data) => dispatch(uploadImage(data))
})
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard)

3 个答案:

答案 0 :(得分:0)

从减速器返回的所有内容都会替换先前的redux状态。因此,在您的情况下,您的初始状态类似于:

{
  images: [],
  ...
}

但是在UPLOAD_IMAGE操作中,您将返回仅具有likes属性的对象:

{
  likes: ...
}

因此,以前的状态将被替换,并且您的state.image.images返回undefined。要使用扩展模式解决此问题,请先将先前的状态分配到新状态,然后分配likes数据:

{
  ...previousState,
  likes: ...
}

答案 1 :(得分:0)

正如我在评论中提到的那样,减速器存在问题,您可以通过

进行修复
case UPDATE_IMAGE: 
return {
    images: [ ...state.images, action.newImage[0]]
}

答案 2 :(得分:0)

在@mezba和@Abhay Sehgal的帮助下

我找到了一个可行的解决方案,谢谢大家

 case UPLOAD_IMAGE:
            const newState = {...state}
            const myImages = newState.images // old images

            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,
                        created_at: new Date().toLocaleString().replace(',', ''),
                        updated_at: new Date().toLocaleString().replace(',', '')
                    },
                    myImages[0]

                ]

            }