React redux свойство объекта prop undefined - PullRequest
1 голос
/ 07 августа 2020

Я новичок в React Redux. Я не уверен, что не так с моим кодом. На терминале нет ошибки, но когда я смотрю в браузер, появляется TypeError. ItemsProduct был на реквизите. Мне было интересно, почему он возвращает ошибку, когда я пытаюсь получить доступ к свойствам.

productDescription. js

import React, { Component } from "react";
import { Link } from "react-router-dom";

import { connect } from "react-redux";
import axios from "axios";

import {
  fetchProductsRequests,
  fetchProductsSuccess,
  fetchProductError,
} from "../../actions/productActions";

class ProductDescription extends Component {
  componentDidMount() {
    this.props.fetchProducts();
  }

  render() {
    return (
      <>
        <div className="grid grid-cols-3 gap-6 mb-10">
          <div className="col-start-2 col-end-4">
            <h4>{this.props.itemsProduct[0].name}</h4>
          </div>
        </div>
      </>
    );
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    itemsProduct: state.rootProduct.products.filter(
      (prod) => prod.id == ownProps.match.params.id
    ),
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    fetchProducts: () => {
      dispatch(fetchProductsRequests());
      axios
        .get("http://localhost:3000/js/products.json")
        .then((response) => {
          dispatch(fetchProductsSuccess(response.data));
        })
        .catch((error) => {
          dispatch(fetchProductError(error.message));
        });
    },
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(ProductDescription);

productActions. js

export const FETCH_PRODUCTS_REQUESTS = "FETCH_PRODUCTS_REQUESTS";
export const FETCH_PRODUCTS_SUCCESS = "FETCH_PRODUCTS_SUCCESS";
export const FETCH_PRODUCTS_ERROR = "FETCH_PRODUCTS_ERROR";

export const fetchProductsRequests = () => {
  return {
    type: FETCH_PRODUCTS_REQUESTS,
  };
};

export const fetchProductsSuccess = (product) => {
  return {
    type: FETCH_PRODUCTS_SUCCESS,
    payload: product,
  };
};

export const fetchProductError = (error) => {
  return {
    type: FETCH_PRODUCTS_ERROR,
    payload: error,
  };
};

productReducer. js

const initialState = {
  loading: true,
  products: [],
  error: "",
};

const productReducer = (state = initialState, action) => {
  switch (action.type) {
    case "FETCH_PRODUCTS_REQUESTS":
      return {
        ...state,
        loading: true,
      };

    case "FETCH_PRODUCTS_SUCCESS":
      return {
        loading: false,
        products: action.payload,
        error: "",
      };

    case "FETCH_PRODUCTS_ERROR":
      return {
        loading: false,
        products: [],
        error: action.payload,
      };
    default:
      return state;
  }
};

export default productReducer;

Root Reducer

import { combineReducers } from "redux";

import productReducer from "./productReducer";

const rootReducer = combineReducers({
  rootProduct: productReducer,
});

export default rootReducer;

1 Ответ

1 голос
/ 07 августа 2020

Вы можете быстро проверить, поступают ли данные с вашего топора ios, сделав это (это предотвратит любые неопределенные или нулевые значения)

dispatch(fetchProductsSuccess(response.data || 'no data'));

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

case "FETCH_PRODUCTS_SUCCESS":
      return {
        ...state,
        loading: false,
        products: action.payload,
        error: "",
      };

    case "FETCH_PRODUCTS_ERROR":
      return {
        ...state,
        loading: false,
        products: [],
        error: action.payload,
      };

Ваш

itemsProduct: state.rootProduct.products.filter(
      (prod) => prod.id == ownProps.match.params.id
    ),

может вернуть пустой массив, что означает, что вы не сможете получить этот объект в своем представлении

<h4>{this.props.itemsProduct[0].name}</h4>
...