ошибка типа реакции при получении нового состояния массива - PullRequest
1 голос
/ 16 июня 2019

Я пытаюсь преобразовать этот код

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

к редуктору, вот моя попытка

Редуктор сниппета

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(',', '')
        }

    ]

}

На данный момент изображения [] отображаются в компоненте панели мониторинга, и он извлекает изображения из редуктора case GET_IMAGES:. Проблема возникает при загрузке изображения. Я получаю ошибку

TypeError: Невозможно прочитать свойство 'length' из неопределенного

и при обновлении новые загруженные изображения отображаются в итерации карты.

Я предполагаю, что старые изображения содержатся в массиве, а новые изображения находятся в массиве внутри объекта, я думаю, я не знаю.

старая структура данных изображений (отредактировано для конфиденциальности)

[
  {
    "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 голосов
/ 16 июня 2019

Как я уже упоминал в комментарии, в вашем редукторе есть проблема, вы можете исправить ее с помощью

case UPDATE_IMAGE: 
return {
    images: [ ...state.images, action.newImage[0]]
}
0 голосов
/ 16 июня 2019

с помощью @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]

                ]

            }
0 голосов
/ 16 июня 2019

Все, что вы возвращаете из редуктора, заменяет предыдущее состояние редукции. Итак, в вашем случае ваше начальное состояние было примерно таким:

{
  images: [],
  ...
}

Но в действии UPLOAD_IMAGE вы возвращаете объект только с likes свойством:

{
  likes: ...
}

Таким образом, предыдущее состояние заменяется этим, а ваш state.image.images возвращает undefined. Чтобы решить эту проблему, используйте шаблон распространения, сначала назначьте предыдущее состояние в новое состояние, затем присвойте likes data:

{
  ...previousState,
  likes: ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...