dva Reducers与Effects的使用介绍

3 篇文章 1 订阅
介绍
dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
定义model
dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。
Reducers

在 model 文件夹下新建products.js文件

export default {
    namespace:"products",
    state:[],
    reducers:{
        'delete'(state,{payload:id}){
        let _state=JSON.parse(JSON.Stringfy(state))
            return _state.filter(item=>item.id!==id)
        },
        'add'(state){
            console.log("state",state);
            return [...state,{name:"umi",id:3}]
        }
    },
}
  • namespace model 的命名空间,同时也是他在全局 state 上的属性,只能用字符串,不支持通过 . 的方式创建多层命名空间。
  • state 是初始值,优先级低于传给 dva() 的 opts.initialState(index.js文件中定义)。
  • reducers 用于处理同步操作,唯一可以修改 state 的地方。由 action 触发。格式为 (state, action) => newState 或 [(state, action) => newState, enhancer]。
使用

直接通过dispatch进行提交,参数包括type,payload(payload指传递的数据,可省略)

const handleDelete=(id)=>{
    dispatch({
        type: 'products/delete',
        payload: id,
      });
}
 const addData=()=>{
    dispatch({
        type: 'products/add',
      });
 }
effects

以 key/value 格式定义 effect。用于处理异步操作和业务逻辑,不直接修改 state。由 action 触发,可以触发 action,可以和服务器交互,可以获取全局 state 的数据等等。
格式为 (action, effects) => void 或 [(action, effects) => void, { type }]。

新建一个一个model/user.js

import  {getList} from "../api/index"
export default {
    namespace:"user",
    state:[],
    reducers:{
    },
     effects:{
       *getList(payload,{call,put}){
       //payload可写成{payload},还可以调用回调,{payload,callback}这种方式使用是非常不优美的,可以改成dataCallBack这种方式
       const { resolve } = payload;
        const data= yield  call(getList, '/user');//异步请求接口 (getList指请求数据的接口)
        yield put({ type: 'products/add'});  //调用reducer
        !!resolve && resolve(data);
            yield put({ type: 'products/add'});  //调用reducer     
        }
    }
}   

api/index.js文件

export const getList= ()=>{
    return new Promise((resolve,reject)=>{  
         fetch("./data.json",{method:"get"}).then(res =>
            {
                return  res.json()
            })
          .then((result) => {
                console.log("result",result.list)
                resolve(result.list) 
            },
            (error) => {
                reject(error)
                console.log(error)
            }
          )
    })
}

const dataCallBack=()=>{
    return new Promise((resolve)=>{
         dispatch({
        type: 'user/getList',
        payload:{resolve}
      })
    }).then((res)=>{
        console.log("Data",res)
      })
}

页面调用

const getData=()=>{
     dispatch({
        type: 'user/getList',
        payload:"ceshi"
      });
}
select
用于从 state 里获取数据。
state:{user:"ssss"},
const users = yield select(state => state.user);
错误处理
全局错误处理
 dva 里,effects 和 subscriptions 的抛错全部会走 onError hook,所以可以在 onError 里统一处理错误。
const app = dva({
  onError(e, dispatch) {
    console.log(e.message);
  },
});
本地错误处理
如果需要对某些 effects 的错误进行特殊处理,需要在 effect 内部加 try catch 。
app.model({
  effects: {
    *addRemote() {
      try {
        // Your Code Here
      } catch(e) {
        console.log(e.message);
      }
    },
  },
});
Subscription
subscriptions 是订阅,用于订阅一个数据源,然后根据需要 dispatch 相应的 action。数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。格式为 ({ dispatch, history }) => unsubscribe 。
app.model({
  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(({ pathname }) => {
        if (pathname === '/users') {
          dispatch({
            type: 'users/fetch',
          });
        }
      });
    },
  },
});

dva中,Reducer 用于处理状态的变化,它接收旧的 state 和 action,然后返回新的 state。下面是使用 dva 中的 Reducer 的示例代码: ```javascript // models/example.js export default { namespace: 'example', state: { data: [], }, reducers: { saveData(state, { payload }) { return { ...state, data: payload, }; }, updateData(state, { payload }) { const { id, newData } = payload; const newDataList = state.data.map(item => { if (item.id === id) { return { ...item, ...newData, }; } return item; }); return { ...state, data: newDataList, }; }, }, }; ``` 在上述示例中,我们定义了一个 `example` 模型,它具有一个初始状态 `state`,其中包含一个名为 `data` 的数组。然后,我们在 `reducers` 对象中定义了两个处理函数:`saveData` 和 `updateData`。 - `saveData` 函数用于存储数据。它接收一个 `payload` 参数,该参数包含要保存的新数据。通过使用对象展开运算符 `...` 来更新状态中的 `data` 数组,将其替换为新的数据。 - `updateData` 函数用于更新数据。它接收一个 `payload` 参数,该参数包含要更新的数据的 `id` 和新的数据对象 `newData`。我们使用 `map` 方法遍历状态中的 `data` 数组,找到与给定 `id` 匹配的项,并使用对象展开运算符 `...` 将新数据合并到该项中。最后,我们返回更新后的 `data` 数组。 在页面组件中,可以通过 `dispatch` 方法来触发 Reducer,并传递相应的 action。 ```javascript import React from 'react'; import { connect } from 'dva'; function ExamplePage({ dispatch, example }) { const handleSaveData = () => { const newData = ['data1', 'data2', 'data3']; dispatch({ type: 'example/saveData', payload: newData }); }; const handleUpdateData = (id, newData) => { dispatch({ type: 'example/updateData', payload: { id, newData } }); }; return ( <div> <button onClick={handleSaveData}>Save Data</button> <button onClick={() => handleUpdateData(1, { name: 'New Name' })}>Update Data</button> {example.data.map((item, index) => ( <div key={index}>{item}</div> ))} </div> ); } export default connect(({ example }) => ({ example }))(ExamplePage); ``` 在上述示例中,我们在页面组件中定义了两个按钮点击事件的处理函数:`handleSaveData` 和 `handleUpdateData`。通过调用 `dispatch` 方法并传入相应的 action,我们可以触发对应的 Reducer。 这就是在 dva使用 Reducer 的基本示例。你可以根据实际需求编写更复杂的 Reducer 函数来处理状态的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值