中间件
中间件就是为原来的代码添加一些功能。而且只有添加store.dispatch
方法(action发起之后,到达reducer之前)才合适。
使用
从redux中引入applyMiddleware
方法,并且引入要使用的中间件,在创建store的时候,之前我们只说过两个参数,中间件可以通过第三个参数传入。
import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
const store = createStore(
reducer,
initial_state,
applyMiddleware(logger)
);
如果有多个中间件,注意是有顺序的要求的。使用前查看一下文档。
具体中间件是怎么实现的就不说了,可以看文档
异步
基本思路
1. Action的改变
在同步操作中,只需要发出一种Action,而异步操作则需要发出三种。可以通过给action
添加一个status
属性,也可以写三个不同的type
来区分这三种action,一般选择后者。
2.state的改变
当然state
也要进行改造,需要添加三个属性。
-
isFetching:是否正在加载,控制加载界面的显示和隐藏。
-
didInvalidate:数据是否过时
-
lastUpdated:最后的更新时间
在实际应用中,还需要添加fetchedPageCount
和nextPageUrl
这种和分页有关的state。
redux-thunk
action创建函数
之前同步操作时,我们的action创建函数返回一个对象,使用redux-thunk
action可以返回一个函数。这个action创建函数就成为了thunk
。
import thunk from 'redux-thunk';
import fetch from 'cross-fetch'
export const REQUEST_POSTS = 'REQUEST_POSTS'
function requestPosts(subreddit) {
return {
type: REQUEST_POSTS,
subreddit
}
}
export const RECEIVE_POSTS = 'RECEIVE_POSTS'
function receivePosts(subreddit, json) {
return {
type: RECEIVE_POSTS,
subreddit,
posts: json.data.children.map(child => child.data),
receivedAt: Date.now()
}
}
export const INVALIDATE_SUBREDDIT = ‘INVALIDATE_SUBREDDIT’
export function invalidateSubreddit(subreddit) {
return {
type: INVALIDATE_SUBREDDIT,
subreddit
}
}
export fetchPost = subreddit =>{
//这里把dispatch方法传递给函数,让它自己也可以dispatch action
return function(dispatch,getState){
//更新应用的state,表示请求发起了
dispatch(requestPosts(subreddit))
return fetch(`http://www.subreddit.com/r/${subreddit}.json`)
.then(
response => response.json()
)
.then(
//异步操作完成之后,再发一个action表示操作结束。
json=> dispatch(receivePosts(subreddit,json))
)
}
}
redux-api-middleware
安装
npm install redux-api-middleware --save
如下场景,点击添加用户时执行下面代码
import { RSAA } from 'redux-api-middleware';
export const addUsers = () => ({
[RSAA]: {
endpoint: 'http://rap2api.taobao.org/app/mock/22711/add',
headers: { 'Content-Type': 'application/json' },
method: 'POST',
credentials: same-origin,
body: {
userName: '哈哈'
},
types: [
{
type: ADD_USER,
payload: action => ({ endpoint: action }),
meta: { source: 'user' }
},
ADD_USER_SUCCESS,
FAILURE
]
}
});
[ADD_USER]: (state, action) => {
console.log(action);
return {
...state
};
},
[ADD_USER_SUCCESS]: (state, action) => {
console.log(action);
return {
...state,
user: action.payload.user
};
},
[FAILURE]: (state, action) => {
console.log(action);
return {
...state
};
}
-
credentials:是否发送cookie,same-origin(同源发送)、include(一直发送,即使跨域)、omit (默认不发送)
-
types:该数组中依次是请求前、请求成功、请求失败对应的type。(如果不做任何传值的的话可以只写type字段)
- payload:请求的结果,成功的话有获取的数据,失败的话是失败信息。
- meta:元属性,携带的信息(或参数)。
-
body:请求方式为post的时候,用来传递参数,如果是get直接拼接在url后。
纯属自己的理解,不对的地方欢迎指出。。。
网友评论