Ошибка типа: невозможно прочитать свойство 'carts' из null - PullRequest
2 голосов
/ 12 октября 2019

Я впервые с Redux, поэтому, пожалуйста, потерпите меня, потому что я не совсем понимаю, как все это работает. Я пытаюсь получить доступ к своему магазину Redux в CartPlantContainer.js. Когда я console.log(this.props.user) я получаю:

{id: 5, name: "b", email: "b", carts: Array(1)}

Но когда я console.log (this.props.user.carts) я получаю ошибку:

TypeError: Не могу прочитатьсвойство 'carts' of null

Я не совсем уверен, что я делаю неправильно. Я просто хочу иметь возможность передать this.props.user.carts следующему компоненту CartPlants, чтобы я мог перебирать тележку и отображать все растения в корзине.

Если вам нужна дополнительная информация, пожалуйста, дайте мне знать. Я был бы рад отправить еще немного моего кода. Новичок здесь, поэтому, пожалуйста, постарайтесь использовать как можно больше терминов для неспециалистов. Заранее спасибо!

import React, { Component } from 'react'
import {connect} from 'react-redux'
import CartPlants from '../components/CartPlants'

class CartPlantContainer extends Component {

    render() {

        // This prints fine:
        console.log(this.props.user); // Displays "{id: 5, name: "b", email: "b", carts: Array(1)}"

        // This fails:
        console.log(this.props.user.carts); // Throws TypeError: Cannot read property 'carts' of null

        return (
            <div>
              <CartPlants />
            </div>
        )
    }
}

const mapStateToProps = state => ({
    user: state.user.user
})


export default connect(mapStateToProps)(CartPlantContainer)

И мой редуктор для пользователя.

let initialState = {user: {
    id: 0,
    name: "",
    email: "",
    carts: [{}]
    }
}
export function userReducer(state = initialState, action) {
    switch(action.type) {
        case LOGIN_USER: 
            return {
                ...state, 
                user: action.user 
            };
        case ADD_CART_PLANT: 
            return {
                ...state,
                user: {...state.user, carts: [...state.user.carts, action.cart_plant]}
            }
        default:
            return state;
    }
}

В бэкэнде моего API есть корзины, вложенные в пользователя. В магазине это тоже изображено. Я не был уверен, нужно ли мне включать значение по умолчанию для каждого атрибута в User или достаточно задать нулевой объект целиком.

Когда я console.log(this.props.user.carts[0]), я теперь получаю:

{id: 5, checkout: false, user_id: 5, total: 2200, cart_plants: Array(20)}

Но когда я console.log(this.props.user.carts[0].cart_plants) получаю:

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

Я полностьюозадачен тем, что я делаю не так.

ОБНОВЛЕНИЕ:

Я добавил пустой объект к своему initialState и смог console.log(this.props.user.carts[this.props.user.carts.length-1].cart_plants) вернуть массив cart_plants.

Однако попытка отобразить их в отдельной функции generateCartPlants() приводит к ошибке

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


generateCartPlants = () => {

    const currentCart = this.props.user.carts[this.props.user.carts.length - 1]

    const cartPlantData = currentCart.cart_plants.map(cart_plant => { 

    return <div className="cart-plant-card" key={cart_plant.id}>

    <CartPlant id={cart_plant.id} image={cart_plant.plant.image} size={cart_plant.plant.size} price={cart_plant.plant.price} name={cart_plant.plant.name} species={cart_plant.plant.species} exp_level={cart_plant.plant.exp_level} light_required={cart_plant.plant.light_required}     pet_friendly={cart_plant.plant.pet_friendly}/>

    </div>

   })
      return cartPlantData

}

** Есть идеи у кого-нибудь? Мне действительно нужна помощь, чтобы продвинуться вперед в моем проекте, и я действительно застрял. Я могу предоставить больше кода, если необходимо, пожалуйста, дайте мне знать!

1 Ответ

1 голос
/ 12 октября 2019

Вам необходимо установить начальные значения для вашего состояния user в вашем редукторе. В react компоненты монтируются, и сначала проверяются состояния. Ваши данные в конечном итоге извлекаются, но у них должна быть возможность распространяться. В этом помогает задание начального фиктивного значения.

Ваш редуктор может выглядеть следующим образом:

// default values need to be set
const initialState = {
    user: {
        id: 0,
        name: "",
        email: "",
        carts: []
    }
}

export default function userReducer(state = initialState, action) {
    if(action.type === "UPDATE_USER") {
        return { ... state, action.payload };
    }

    // always return the state;
    return state;
}
...