Приложение Redux: не удается прочитать свойство 'filter' из неопределенного - PullRequest
0 голосов
/ 10 ноября 2019

У меня ошибка в моем редукторе: enter image description here

реквизит actual - это время вылета или прибытия самолета, это свойство находится в моем APIструктура:

{"body":{
"departure":[{actual: value},{term: value}],
"arrival":[{....},{......}]}
}

код:

airplanes.js (редуктор)

import { searchFilter } from "../components/app";

export function reducer(state = {}, action) {
  switch (action.type) {
    case "SET_SHIFT":
      return Object.assign({}, state, {
        shift: action.shift
      });
    case "SET_SEARCH":
      return Object.assign({}, state, {
        search: action.search.toLowerCase()
      });
    case "RUN_FILTER":
      var newData = state.data[action.shift].filter(x => {
        return (
          x.actual &&
          x.actual.includes(
            state.day
              .split("-")
              .reverse()
              .join("-")
          )
        );
      });
      return Object.assign({}, state, {
        shift: action.shift || state.shift,
        search: action.search || state.search,
        filteredData: searchFilter(state.search, newData)
      });
    case "LOAD_DATA_START":
      return Object.assign({}, state, {
        day: action.day
      });
    case "LOAD_DATA_END":
      var newData = action.payload.data[state.shift].filter(x => {
        return (
          x.actual &&
          x.actual.includes(
            action.payload.day
              .split("-")
              .reverse()
              .join("-")
          )
        );
      });
      return Object.assign({}, state, {
        data: action.payload.data,
        shift: Object.keys(action.payload.data)[0],
        filteredData: searchFilter(state.search, newData)
      });
    default:
      return state;
  }
}

app.js (основной компонент)

import React from "react";
import { Component } from "react";
import { connect } from "react-redux";
import { fetchData } from "../actions";
import TableData from "./TableData";
import TableSearch from "./TableSearch";
import Header from "./Header";
import Footer from "./Footer";
import "./app.css";

export function searchFilter(search, data) {
  return data.filter(n => n.term.toLowerCase().includes(search));
}

const days = ["23-08-2019", "24-08-2019", "25-08-2019"];

class Root extends React.Component {
  componentDidMount() {
    this.props.onFetchData(days[this.props.propReducer.day]);
  }

  render() {
    const { onFilter, onSetSearch, onFetchData } = this.props;

    const { search, shift, data, filteredData } = this.props.propReducer;

    console.log(filteredData);

    return (
      <div>
        <Header/>
        <h1>SEARCH FLIGHT</h1>
        <TableSearch
          value={search}
          onChange={e => onSetSearch(e.target.value)}
          onSearch={() => onFilter()}
        />

        {days &&
          days.map((day, i) => (
            <button
              key={day}
              onClick={() => onFetchData(day)}
              className={i === day ? "active" : ""}
            >
              {day}
            </button>
          ))}
        <br />
            <div className="buttonShift">
        {data &&
          Object.keys(data).map(n => (

            <button 
              data-shift={n}
              onClick={e => onFilter({ shift: e.target.dataset.shift })}
              className={n === shift ? "active" : "noActive"}
            >
              {n} 
            </button>
          ))}
          </div>
        {data && <TableData data={filteredData} />}
        <Footer/>
      </div>
    );
  }
}

export const ConnectedRoot = connect(
  state => state,
  dispatch => ({
    onFilter: args => dispatch({ type: "RUN_FILTER", ...args }),
    onSetSearch: search => dispatch({ type: "SET_SEARCH", search }),
    onFetchData: day => dispatch(fetchData(day))
  })
)(Root);

кстати функция searchFilter записана свойством term, а не свойством actual. Может быть, проблема отчасти связана с этим, но не только с этим, потому что я пытался заменить term на actual, но ошибка осталась.

Как исправить эту ошибку?

1 Ответ

1 голос
/ 10 ноября 2019

Дано onFilter создателю действия в app.js:

onFilter: args => dispatch({ type: "RUN_FILTER", ...args })

При вызове без первого аргумента:

<TableSearch ... onSearch={() => onFilter()} />

Тогда в airplanes.js редукторе action.shift равноне определено, поэтому state.data[action.shift] тоже не определено и state.data[action.shift].filter является ошибкой типа.

Чтобы исправить, вы можете использовать значение по умолчанию :

state.data[action.shift || state.shift].filter

Однако есть дополнительная проблема, внутри TableSearch.js вы звоните:

<button ... onClick={() => onSearch(value)}>

Так что вы не должны игнорировать значение в app.js:

<TableSearch ... onSearch={(value) => onFilter({search: value})} />

... и используйте action.search || state.search внутри вашего .filter(...) в зависимости от бизнес-логики.

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