Reducer和Effect
Opened this issue · 0 comments
bai3 commented
Reducer
reducer 是一个函数,接受state和action,返回老的或者新的state。即:(state,action) => state
增删改
以todo为例
app.model({
namespace: 'todos',
state: [],
reducers: {
add(state, { payload: todo}) {
return state.concat(todo);
},
remove(state, { payload: id }){
return state.filter(todo => todo.id !== id);
},
update(state, { payload: updatedTodo}){
return state.map(todo => {
if(todo.id === updatedTodo.id) {
return {...todo,...updatedTodo};
}else{
return todo;
}
})
}
}
})
嵌套数据的增删改
建议最多一层嵌套,以保持state的扁平化,深层嵌套会让reducer很难写和难以维护。
app.model({
namespace: 'app',
state: {
todos: [],
loading: false
},
reducer: {
add(state, { payload:todo }) {
const todos = state.todos.concat(todo);
return { ...state,todo};
}
}
})
Effect
示例:
app.model({
namespace: 'todos',
effect: {
*addRemote({ payload: todo}, {put, call}){
yield call(adddTodo, todo);
yield put({ type:'add', payload: todo})
}
}
})
Effects
-
put
用户触发action
yield put({ type: 'todos/add', payload: 'Learn Dva'}
-
call
用于调用异步逻辑,支持promise
const result = yield call(fetch, '/todos')
-
select、
用于从state里获取数据
const todos = yield select(state => state.todos);
错误处理
全局错误处理
dva里,effects和subsciptions的抛错全部会走onError hook,所以可以在onError里统一处理错误
const app = dva({
onError(e,dispatch) {
console.log(e.message)
}
})
在effects里的抛错和reject的promise就都会被捕获到了
本地错误处理
如果需要对某些effects的错误进行特殊处理,需要再effect内部加try catch。
app.model({
effects: {
*addRemote(){
try{
}catch(e){
console.log(e.message)
}
}
}
})
异步请求
GET和POST
import { request } from "../util/request";
//GET
request('/api/todos')
//POST
request('/api/todos',{
method: 'POST',
body: JSON.stringify({a:1})
})
统一错误处理
假如约定后台返回以下格式时,做统一的错误处理
{
status: 'error',
message: ''
}
编辑 utils/request.js 加入以下中间件:
function parseErrorMessage({data}){
const {status, message} = data;
if(status === 'error'){
throw new Error(message)
}
return { data }
}
然后,这类错误就会走到onError hook里