简体   繁体   中英

ReactJS: TypeError: Cannot read property 'includes' of undefined

I want to apologize in advance because I'm very new using React Framework and if my code writing is not clean. I'm currently creating a --Filter By-- dropdown in my code using selector for my JSON data from the API. But I keep getting this kind of error in my code. I've been dealing with this for the past 2 days and I haven't been able to fix this.

My Code:

selector.js

import { createSelector } from "reselect";

const getItems = (state) => [state.shop];
const getValue = (state) => state.category;

export const getFilteredItems = createSelector(
  [getItems, getValue],
  (items, value) => {
    items =
      value == "ALL"
        ? items
        : items.filter((item) => item.productIdentifier.includes(value));
  }
);

catalog.jsx --> component

import React, { Component } from "react";
import "./CatalogStyle.css";
import { addToCart, getItems } from "../../actions/projectActions";
import { getFilteredItems } from "../../selectors/selector";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Link } from "react-router-dom";

class Catalog extends Component {
  constructor(props) {
    super(props);
    this.state = {
      category: "ALL",
    };
  }

  componentDidMount() {
    this.props.getItems();
  }

  filterByCategory = (e) => {
    let filterValue = e.target.value;
    this.setState({ category: filterValue });
  };

  _addToCart = (id) => {
    this.props.addToCart(id);
  };

  render() {
    const { items } = this.props.items;

    return (
      <React.Fragment>
        <div>
          <label>
            Filter By:
            <select
              value={this.state.value}
              onChange={(e) => {
                this.filterByCategory(e);
              }}
            >
              <option value="ALL">All</option>
              <option value="FD">Food</option>
              <option value="CL">Clothes</option>
            </select>
          </label>
        </div>
        <div className="table">
          {items.map((item) => (
            <div className="card" key={item.id}>
              <img
                className="imageProperty"
                src={require("../layout/images/buat_gambaran_product/u138.jpg")}
              ></img>
              <h3 className="productName">{item.productName}</h3>
              <p className="PriceAmmount">{item.productPrice}</p>
              <p>{item.productDescription}</p>
              <Link to="/checkout">
                <button
                  onClick={() => {
                    this._addToCart(item.id);
                  }}
                >
                  add
                </button>
              </Link>
            </div>
          ))}
        </div>
      </React.Fragment>
    );
  }
}

Catalog.propTypes = {
  getItems: PropTypes.func.isRequired,
  items: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
  items: getFilteredItems(state),
});

const mapDispatchToProps = (dispatch) => {
  return {
    addToCart: (id) => {
      dispatch(addToCart(id));
    },
    getItems: () => {
      dispatch(getItems());
    },
  };
};

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

my reducer.js to get all items

case GET_ITEMS:
      return {
        ...state,
        items: action.payload,
      };

my projectActions.js for the getItems

export const getItems = () => async (dispatch) => {
  const res = await axios.get("http://localhost:8080/api/project/all");
  dispatch({
    type: GET_ITEMS,
    payload: res.data,
  });
};

JSON

shop : {
    items : [
        0{
          "id": 1,
          "productName": "shoes",
          "productIdentifier": "CL001",
          "productDescription": "adidas kicks boir",
          "productPrice": 2000,
          "productStock": 200,
          "created_at": "2020-51-28",
          "updated_at": null
         }
        1{
          "id": 2,
          "productName": "burger",
          "productIdentifier": "FD001",
          "productDescription": "charsiu berger",
          "productPrice": 2000,
          "productStock": 200,
          "created_at": "2020-51-28",
          "updated_at": null
         }
      ],
    }

PS. please don't mind created_at and updated_at .

error logs

Uncaught TypeError: Cannot read property 'includes' of undefined
    at selector.js:9
    at Array.filter (<anonymous>)
    at selector.js:9
    at index.js:69
    at index.js:30
    at index.js:82
    at index.js:30
    at Function.mapStateToProps [as mapToProps] (Catalog.jsx:83)
    at mapToPropsProxy (wrapMapToProps.js:41)
    at Function.detectFactoryAndVerify (wrapMapToProps.js:50)
    at mapToPropsProxy (wrapMapToProps.js:41)
    at handleFirstCall (selectorFactory.js:22)
    at pureFinalPropsSelector (selectorFactory.js:63)
    at connectAdvanced.js:208
    at mountMemo (react-dom.development.js:16875)
    at Object.useMemo (react-dom.development.js:17187)
    at useMemo (react.development.js:1614)
    at ConnectFunction (connectAdvanced.js:193)
    at renderWithHooks (react-dom.development.js:16317)
    at updateFunctionComponent (react-dom.development.js:18363)
    at updateSimpleMemoComponent (react-dom.development.js:18303)
    at updateMemoComponent (react-dom.development.js:18208)
    at beginWork$1 (react-dom.development.js:20234)
    at HTMLUnknownElement.callCallback (react-dom.development.js:337)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:386)
    at invokeGuardedCallback (react-dom.development.js:439)
    at beginWork$$1 (react-dom.development.js:25768)
    at performUnitOfWork (react-dom.development.js:24685)
    at workLoopSync (react-dom.development.js:24658)
    at performSyncWorkOnRoot (react-dom.development.js:24247)
    at react-dom.development.js:12285
    at unstable_runWithPriority (scheduler.development.js:701)
    at runWithPriority$2 (react-dom.development.js:12231)
    at flushSyncCallbackQueueImpl (react-dom.development.js:12280)
    at flushSyncCallbackQueue (react-dom.development.js:12268)
    at discreteUpdates$1 (react-dom.development.js:24401)
    at discreteUpdates (react-dom.development.js:1439)
    at dispatchDiscreteEvent (react-dom.development.js:5914)

Thanks in advance for anyone that could help me.

The problem is that in the items array you have no objects with the property productIdentifier , or, maybe, you have some objects without this prop. It call error:

selector.js

import { createSelector } from "reselect";

const getItems = (state) => [state.shop];
const getValue = (state) => state.category;

export const getFilteredItems = createSelector(
  [getItems, getValue],
  (items, value) => {
    items =
      value == "ALL"
        ? items
        : items.filter((item) => item.productIdentifier.includes(value)); //<== this
  }
);

Welcome to Stack Overflow and in React technology.

Your getItems objects are in array type so you need to loop through the variable.

So due to directly applying this way item.productIdentifier.includes(value)) it will throw you an error of Undefined as in the item the second thing is index of array and then in that your productIdentifier object key is defined.

Review the code snippet at below.

 var items = [ { "id": 1, "productName": "shoes", "productIdentifier": "CL001", "productDescription": "adidas kicks boir", "productPrice": 2000, "productStock": 200, "created_at": "2020-51-28", "updated_at": null }, { "id": 2, "productName": "burger", "productIdentifier": "FD001", "productDescription": "charsiu berger", "productPrice": 2000, "productStock": 200, "created_at": "2020-51-28", "updated_at": null } ] console.log(items) items.map((item) => { let prodIdentifier = item.productIdentifier.includes('FD001') console.log(prodIdentifier) })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM