我有错误:
Redux我刚刚开始学习,请帮助纠正我的代码,使我的Redux应用程序终于可以在纯React上运行。
所有项目在这里,我将只编写一些主要项目文件在这里,我将只编写一些主要项目文件。
在这里,我只写一些主要的项目文件
在这里,我只写一些主要的项目文件
在这里,我只写一些主要的项目文件
App.js(组件):
foo
bar
foo
bar
减速器:
export function searchFilter (search, data) {
return data.filter(n => n.term.toLowerCase().includes(search));
}
export const days = ["23-08-2019", "24-08-2019", "25-08-2019"];
class Root extends React.Component {
componentDidMount() {
this.props.onFetchData(this.props.day);
}
render() {
const { search, shift, data, filteredData, onFilter, onSetSearch, onFetchData } = this.props;
return (
<div>
<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 />
{data && Object.keys(data).map(n => (
<button data-shift={n}
onClick={(e) => onFilter({ shift: e.target.dataset.shift })}
className={n === shift ? "active" : ""}>{n} shift</button>
))}
{data && <TableData data={filteredData} /> }
</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);
答案 0 :(得分:1)
问题是您没有从API(404
)中获得任何回报。请参见下图。
这是因为加载组件时的${day}
值为undefined
。因此,您的完整请求URL为https://api.iev.aero/api/flights/undefined
,该请求什么也不返回。
现在您要调度LOAD_DATA_START
,因此,当您到达减速器并按下case "LOAD_DATA_START
行时,action.day
仍为undefined
。因此,对于action.data
,您得到的是一个空数组。这使我们进入LOAD_DATA_END
,在这里您将shift
的状态值设置为等于Object.keys(action.data)[0]
。由于action.data
为空,因此Object.keys(action.data)[0]
为undefined
,您的应用无法使用undefined
进行过滤。您需要具有this.state.day
的默认值,并在初始获取时使用该默认值。
更新1
您需要在初始访存中传递默认值。在您的componentDidMount
中尝试以下操作:
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]);
}
...
}
无需导出days
数组,只需将其声明为组件上方的变量即可。
更新2
我已经更新了code sandbox。这里发生了一些变化。
首先,您的redux操作存储在this.props
中,但是您的redux状态存储在this.props.propReducer
中,因此在渲染中,我更改了变量,使它们指向正确的位置。
接下来,您正在SET_SHIFT
之后立即调度LOAD_DATA_END
,并将data
作为有效负载传递。这是将state.shift
设置为从初始提取返回的数据。因此,除了您首次尝试在state.shift
中进行抓取之外,其他任何时候您都尝试用componentDidMount
过滤数据时,您试图将action.data
分隔为先前所有已提取数据的键。我删除了它,并将其完全设置为单独的操作。
现在,为了正确过滤数据,我在fetchData
中将检索到的数据和传递为LOAD_DATA_END
的有效载荷中的两个值,请参见下文
dispatch({ type: "LOAD_DATA_END", payload: { data, day } });
最后,在"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)
});
这里发生的事情是,首先您用action.payload.data
键将state.shift
分开,该键返回一个数组,即到达或离开。然后,我根据哪些航班具有actual
(我假设这是实际的到达/离开的日期和时间)来过滤此数组,其中包括过去的日期。不过,我必须调换日期,因为在actual
中,时间看起来像2019-08-24T00:27:49Z
,而白天看起来是24-08-2019
。这也是为什么我使用includes
而不使用===
的原因,因为actual
包含的信息不仅是日期,还包含时间。现在,您的数据已正确过滤,可以传递到最终过滤searchFilter
中,我将由您决定根据用户输入(时间,航班号,航站楼等)来确定最佳过滤方式
如果您检查码笔,现在应该可以按班次和日期进行过滤。