首先我们需要定义一个异步请求,从后端服务器接口获取数据,然后根据返回的 JSON 数据,通过发送对应的 Action 来改变 State 的状态。
下面是一个模拟请求 JSON 数据并使用这些数据渲染页面的例子,类似这样的一个 JSON 数据:
{
"topicList": [
{ "id": 1, "title": "Topic 1" },
{ "id": 2, "title": "Topic 2" }
],
"articleList": [
{ "id": 1, "title": "Article 1" },
{ "id": 2, "title": "Article 2" }
],
"recommendList": [
{ "id": 1, "title": "Recommend 1" },
{ "id": 2, "title": "Recommend 2" }
]
}
1. 初始代码
以下是初始代码:
componentDidMount() {
axios.get('/api/home.json').then((res) => {
const result = res.data.data;
const action = {
type: 'change_home_data',
topicList: result.topicList,
articleList: result.articleList,
recommendList: result.recommendList
};
this.props.changeHomeData(action);
})
}
2 优化组件逻辑
上面的代码中,在 UI 组件的生命周期函数 componentDidMount 中发送 Ajax 请求并修改 State,这并不是一个好的实践,我们应该将逻辑处理放在一个函数中,然后只调用这个函数来执行操作,这样可以让组件更加简洁。
以下是优化后的代码:
javascriptCopy code
componentDidMount() {
this.props.changeHomeData();
}
这个函数中的操作实际上是创建一个 Action 并将其分发到 Reducer 进行数据更新。具体实现如下:
javascriptCopy code
const mapDispatchToProps = (dispatch) => ({
changeHomeData() {
const action = actionCreators.getHomeInfo();
dispatch(action);
}
});
Reducer 处理如下:
phpCopy code
import { fromJS } from 'immutable';
import * as constants from './constants';
const defaultState = fromJS({
topicList: [],
articleList: [],
recommendList: []
});
export default (state = defaultState, action) => {
switch (action.type) {
case constants.CHANGE_HOME_DATA: {
console.log(action);
return state.merge({
topicList: fromJS(action.topicList),
articleList: fromJS(action.articleList),
recommendList: fromJS(action.recommendList)
});
}
default: {
return state;
}
}
}
3. 异步请求的发送
在上面的代码中,我们使用了thunk中间件来允许在action中进行异步操作。具体的实现可以在actionCreators中看到:
javascriptCopy code
import axios from "axios";
import * as constants from './constants';
const changeHomeData = (result) => ({
type: constants.CHANGE_HOME_DATA,
topicList: result.topicList,
articleList: result.articleList,
recommendList: result.recommendList
});
export const getHomeInfo = () => {
return (dispatch) => {
axios.get('/api/home.json').then((res) => {
const result = res.data.data;
dispatch(changeHomeData(result));
})
}
};
上面的代码中,changeHomeData函数实际上是一个真正发送的action。在getHomeInfo函数中,我们使用异步请求来获取JSON中需要的数据并创建并分发一个对应的action来更新store的状态。
4. 回顾thunk
当我们需要在 Redux 中进行异步操作时,可以使用 Redux 中间件来处理异步行为。其中,Redux Thunk 是一种常用的中间件,它允许我们在 action creators 中返回一个函数而不是一个普通的 action 对象。
这个函数接收两个参数:dispatch 和 getState。dispatch 是用于派发 action 的函数,而 getState 是用于获取当前的 state 的函数。这样,在异步操作中,我们就可以在 action creator 中进行一些异步操作,例如通过 axios 发送异步请求,等待请求响应后再通过 dispatch 发送一个真正的 action。
在上面的代码中,我们定义了一个名为 getHomeInfo 的 action creator,它返回了一个函数。在这个函数中,我们发送了一个异步请求来获取远程数据,并在响应后通过 dispatch 发送一个名为 changeHomeData 的 action 来更新 store 中的数据。
在 Redux 中使用 Thunk 可以让我们更方便地处理异步操作,而不必在组件中处理异步操作逻辑。同时,使用 Thunk 还可以使代码更加简洁易懂。