Действие редуктора не обновляется динамически - PullRequest
0 голосов
/ 19 февраля 2019

Я создаю базовое приложение CRUD, используя React / Redux с Rails API, и когда я отправляю автомобиль в форме автомобиля, я получаю сообщение об ошибке, но при обновлении браузера отображается машина.

Ошибка говорит Uncaught TypeError: Cannot read property 'map' of undefined в строке 20 моего файла Cars.js:

    import React, { Component } from 'react';
import { connect } from 'react-redux';

import CarCard from '../components/CarCard';
import CarForm from './CarForm';
import './Cars.css';
import { getCars } from '../actions/cars';


class Cars extends Component {

componentDidMount() {
    this.props.getCars()
}

render() {
    return (
    <div className="CarsContainer">
        <h3>Cars Component</h3> 
        {this.props.cars.cars.map(car => <CarCard key={car.id} car={car} />)}
        <CarForm />
    </div>
    );
}

}

const mapStateToProps = (state) => {
    return ({
        cars: state.cars
    })
}

export default connect(mapStateToProps, { getCars })(Cars);

Вот мой createCar создатель действия:

const addCar = car => {
return {
    type: 'CREATE_CAR_SUCCESS',
    car
}}

И мое createCar асинхронное действие:

export const createCar = car => {
return dispatch => {
    return fetch(`${API_URL}/cars`, {
        method: "POST",
        headers: {
            'Content-type': 'application/json'
        },
        body: JSON.stringify({ car: car })
    })
    .then(response => {
      try {
        return response.json()
      } catch(error) {
        console.log(error);
      }
    })
    .then(cars => {
        dispatch(addCar([car]));
        dispatch(resetCarForm())
    })
    .catch(error => console.log(error + 'createCar POST failed'))
}}

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

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Проблема в том, что когда ваш компонент монтируется, у него нет массива cars, а вместо этого он имеет неопределенное значение.Это происходит потому, что getCars() является асинхронным.

Решение 1: добавляет defaultProp к компоненту:

Component.defaultProps = {
cars: { cars: [] }
}

Решение 2: Добавитьавтомобильный ключ от редуктора initialState

initialState: { cars:{ cars:[] } }
0 голосов
/ 19 февраля 2019

Вы выполняете вызов действия getCars в componentDidMount, и этот метод жизненного цикла вызывается после первого рендеринга, поэтому при первоначальном рендеринге this.props.cars будет неопределенным

Если вы получаете this.props.cars, например

   {
       “cars”: [....]
    }

Затем необходимо выполнить условную проверку перед доступом к объекту машины

Изменить

       {this.props.cars.cars.map(car => <CarCard key={car.id} car={car} />)}

На

         {this.props.cars && this.props.cars.cars.map(car => <CarCard key={car.id} car={car} />)}
0 голосов
/ 19 февраля 2019

Вы выполняете рендеринг до того, как ваше асинхронное действие переводит значения в состояние.Попробуйте вернуть null из рендера, если ваше состояние еще не установлено:

render() {
    if(!this.props.cars.cars){
      return null;
    }
    return (
    <div className="CarsContainer">
        <h3>Cars Component</h3> 
        {this.props.cars.cars.map(car => <CarCard key={car.id} car={car} />)}
        <CarForm />
    </div>
    );
}

Другими словами, если в вашем состоянии нет списка вещей для рендеринга, возвращайте ноль - я думаю выше, если будет работать, но вы можете console.log("Cars in render", this.props.cars), чтобы увидеть, что вы получаете.

Лучший вариант, IMO, это установить ваше начальное состояние так, чтобы this.props.cars было [] итогда вам не нужно возвращать нуль и иметь специальный случай в вашем методе render.Мне нужно было бы обратиться к вашему редуктору, чтобы подсказать, как это сделать, но если вы установите разумное значение по умолчанию / начальное состояние, вы сможете легко это сделать.

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