reactjs - 如何在 useReducer 中进行 api 调用?
问题描述
这是我想重构为功能组件的类组件useReducer
export default class FootballMatchesData extends Component {
constructor(props) {
super(props);
this.state = {
selectedYear: null,
matchData: [],
firstCall: false
};
}
chooseYear = (year) => (e) => {
this.setState({
selectedYear: year
})
axios.get(`https://website?property=${year}`)
.then(res => {
this.setState({ matchData: res.data, firstCall: true })
})
}
render() {
...
}
}
我一直在定义减速器的“CHOOSE_YEAR”案例。我将如何定义这种情况,以便它:
- 更新
selectedYear
- 对 进行 api 调用
https://website?property=${year}
,然后填充matchData
- 更新
firstCall
这是我当前的重构。https://codesandbox.io/s/gracious-pare-um66h?file=/src/FootballMatches.js
解决方案
您似乎对减速器模式不熟悉。Reducers 是一个纯函数,采用状态对象和动作应用于该状态,并返回下一个状态对象。reducer 函数的副作用为零。
在状态更新时使用useEffect
钩子获取数据。year
您可能不想同时为年份列表选项使用锚标签,因为单击它可能会尝试导航或重新加载应用程序/页面。
const initialState = {
selectedYear: null,
competitions: [],
firstCall: false
};
const footballReducer = (state, action) => {
switch (action.type) {
case "CHOOSE_YEAR":
return {
selectedYear: action.year, // <-- save year payload
firstCall: true
};
case "FETCH_BY_YEAR_SUCCESS":
return {
...state, // <-- copy existing state
competitions: action.competitions // <-- save competitions payload
};
default:
throw new Error();
}
};
const FootballMatches = () => {
const [state, dispatchFootball] = useReducer(footballReducer, initialState);
const yearChooseHandler = (year) => {
dispatchFootball({ type: "CHOOSE_YEAR", year });
};
useEffect(() => {
if (state.year) { // <-- ensure year value is truthy since null on initial render
axios.get(`https://website?property=${state.year}`).then((res) => { // <-- access state.year for URL
dispatchFootball({
type: "FETCH_BY_YEAR_SUCCESS",
competitions: res.data,
firstCall: true
});
}
});
}, [state.year]); // <-- year dependency
let years = [2011, 2012, 2013, 2014, 2015, 2016, 2017];
return (
<div>
<div>Select Year</div>
<ul>
{years.map((year, idx) => {
return (
<li
onClick={() => yearChooseHandler(year)} // <-- fix callback so it isn't invoked immediately and cause infinite render looping
key={idx}
>
{year}
</li>
);
})}
</ul>
...
</div>
);
};
推荐阅读
- c++ - gcc 4.6.1 版与 protobuf 兼容吗?
- autodesk-forge - 删除所有模型派生属性?
- laravel - 在 Laravel 中找不到观察者
- blockchain - Hyperledger Besu 是否与 Cosmos IBC 兼容?
- networking - 如何在 SONiC OS 中找到内存缓冲区大小限制?
- javascript - 数组在 reduce()、map() 等内部可用的原因是什么?
- python - Spark使用mappartitions将rdd文本文件转换为列,同时保留空值
- flutter - 如何让 RotateTransition 将我的小部件旋转一半(180 度)
- c# - 使用启动窗口运行 Windows 窗体应用程序
- javascript - 如何在javascript中设置数组对象的键值?