dva做数据管理


dva 基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,今天就讲一下具体的使用

实现的效果:计算器的同步增减及异步修改数据

1.创建ui component

return (
        <>
            
测试组件 Option:
变量:{count || 0}

)

2.创建model(5个api)

const TestModel={
    namespace:"testModel",       // 命名空间,model数据做隔离
    state:{                          // 变量存储,尽量扁平化处理,不要嵌套层级多
        count:1, 
    },
    reducers:{                      // 同redux中的reducer模块,以key/value定义reducer用于处理同步操作,唯一可以修改 state 的地方。由 action 触发
        add(state, { payload}) {
            const count = state.count + payload
            return {...state,count:count}
        },
        reduce(state,{payload}) {
            const count = state.count - payload
            return {...state,count:count}
        },
    },
    effects:{                        // 以 key/value 格式定义 effect。处理异步操作,不直接修改 state。由 action 触发,可以触发 action,可以和服务器交互...
        *changeAsync(_, {call,put}) {
            yield call(delay,500)
            yield put({type:'add',payload:2})
        }
    }, 
   // 以 key/value 格式定义 subscription。subscription 是订阅,用于订阅一个数据源,然后根据需要 dispatch 相应的 action。在 app.start() 时被执行,数据源                    可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。
    subscriptions: {   setup({ dispatch, history }, done) {   return history.listen((location) => {   if (   location.pathname === 'xxx' ) {   dispatch({type:'XXX',payload:XXX})   } }); }, },

   }

3.connect连接:引入connect模块

import {connect} from 'dva'

export default connect(({testModel})=>(
    {
        count:testModel.count,
    }
))(Index)

4.组件内部使用

 ① 获取dva存储的变量:组件自带dispact方法和转换后的变量

 const Index= (dispatch,state1,state2...)=>{

 ② 组件内部修改数据通过dispatch方法

 dispatch({

  type:[namespace]/同步reducer或异步的effects名,

  payload:传入的参数

 })

5.完整代码

test.js

import React,{useRef,useState,useEffect} from 'react'
import {connect} from 'dva'

const ChildComp = (props) =>{
    const {userName,userAge} = props
    return <>   
        

ChildComp子页面获取数据

子页面获取到的姓名:{userName}
子页面获取的年龄:{userAge}
} const Index=({dispatch,count,userName,userAge})=> { const inputRef = useRef() useEffect(()=>{ // console.log('count数据变化了') return () =>{ } },[count]) const handleAdd = () =>{ dispatch({type:'testModel/add',payload:Number(inputRef.current.value)}) } const handleReduce = ()=>{ dispatch({ type:'testModel/reduce', payload:Number(inputRef.current.value) }) } const handleAsync = ()=>{ dispatch({type:'testModel/changeAsync',payload:Number(inputRef.current.value)}) } return ( <>
测试组件 Option:
变量:{count || 0}

) } // const mapStateToProps= (state) =>{ // return { // count:state.testModel.count, // userName:state.testModel.userName, // userAge: state.testModel.userAge // } // } export default connect(({testModel})=>( { count:testModel.count, userName:testModel.userName, userAge:testModel.userAge } ))(Index)

model

const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));

const TestModel={
    namespace:"testModel",
    state:{
        count:1,
        userName:'wang'
    },
    reducers:{
        add(state, { payload}) {
            const count = state.count + payload
            return {...state,count:count}
        },
        reduce(state,{payload}) {
            const count = state.count - payload
            return {...state,count:count}
        },
        changeUserName(state,{payload}) {
            return {...state,...payload}
        }
    },
    effects:{
        *changeAsync(_, {call,put}) {
            yield call(delay,500)
            yield put({type:'add',payload:2})
        }
    }
}
export default TestModel

 界面效果:

return (
        <>
            
测试组件 Option:
变量:{count || 0}

)
subscriptions: { setup({ dispatch, history }, done) { return history.listen((location) => { if ( location.pathname === '/app/admin/weak/vuln' || location.pathname === '/app/admin/weak/vuln/hostadd' || location.pathname.indexOf('/app/admin/weak/vuln/host/') !== -1 ) { dispatch({ type: 'init', payload: { vulnInstanceType: 'serviceManage', }, }); } if ( location.pathname === '/app/admin/weak/vuln/website' || location.pathname === '/app/admin/weak/vuln/websiteadd' || location.pathname.indexOf('/app/admin/weak/vuln/website') !== -1 ) { dispatch({ type: 'init', payload: { vulnInstanceType: 'webserviceManage', }, }); } }); }, },