【问题标题】:Redux app: Cannot read property 'filter' of undefinedRedux 应用程序:无法读取未定义的属性“过滤器”
【发布时间】:2019-11-10 10:00:55
【问题描述】:

我的减速器有错误:

props actual- 这是飞机起飞或到达的时间,这个属性位于我的 API 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。也许问题部分是由于这个,但不仅仅是这个,因为我试图用actual替换term,但错误仍然存​​在。

如何解决这个错误?

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    鉴于app.js 中的onFilter 动作创建者:

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

    在没有第一个参数的情况下调用时:

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

    那么在airplanes.js reducer 中,action.shift 是未定义的,所以 state.data[action.shift] 也是未定义的,state.data[action.shift].filter 是一个 TypeError。

    要修复,您可以使用默认值

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

    但是,还有一个额外的问题,在你调用的TableSearch.js 内部:

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

    所以你不应该忽略app.js中的值:

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

    ...并根据业务逻辑在.filter(...) 中使用action.search || state.search

    【讨论】:

    • 非常感谢您的回答!你能帮我纠正沙盒错误吗?我只是 react 和 redux 的初学者,不明白你写的所有内容以及在哪里修复它。我理解了一些东西,但不是所有的东西。我只是认为它会比我问你要快,在哪里和在哪一行在代码中替换。我的沙盒:codesandbox.io/s/…
    • 请询问不清楚的地方,更好的解释也可能对未来的用户有所帮助。
    • ok:1) 在 aiplanes.js 中我更改了:state.data[action.shift || state.shift].filter,但在下面我有这行:case "LOAD_DATA_END": var newData = action.payload.data[state.shift].filter(x =&gt; { 是否还需要以某种方式进行修改? 2) TableSearch ... onSearch={(value) =&gt; onFilter({search: value})} /&gt; 我应该在 app.js 中写那个吗? 3) 并在 .filter(...) 中使用 action.search || state.search 。我应该在哪个文件和哪些行中更改它?
    • 1) 这取决于您是否使用shift 有效负载分派LOAD_DATA_END 操作 - 可能不是。 2) 是的,在任何使用&lt;TableSearch&gt; 的地方。 3)不知道期望的行为是什么,搜索应该如何工作。但在case "RUN_FILTER":里面的某个地方
    • 我可以给你写一封写在你 github 上的电子邮件吗?写起来会不会比在cmets里方便?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2021-06-03
    • 2019-04-30
    • 2021-11-03
    • 1970-01-01
    • 2019-02-02
    • 2021-11-02
    相关资源
    最近更新 更多