【react框架之dvajs】搞懂这些,dva的数据流你就可以随意拿捏了

【react框架之dvajs】搞懂这些,dva的数据流你就可以随意拿捏了

dva 是开发的 React 应用框架,将React-Router,Redux及异步操作Redux-saga三个 React 工具库包装在一起,简化了 API,让开发 React 应用更加方便和快捷。

数据变化的时机

数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State,所以在 dva 中,数据流向非常清晰简明。

所以得出这个公式 =======》 dva = React-Router + Redux + Redux-saga

数据流模式

同步数据

异步数据

现在看看在dva里面怎么处理公共的数据仓库

实现效果

需要提醒的,项目已经安装好这三个工具,不用再安装。

核心概念

State:一个对象,保存整个应用状态View:React 组件构成的视图层Action:一个对象,描述事件connect 方法:一个函数,绑定 State 到 Viewdispatch 方法:一个函数,发送 Action 到 State

代码实现

routes/IndexPage.js的逻辑

import React from "react";

import { connect } from "dva";

import styles from "./IndexPage.css";

import PropTypes from "prop-types";

import { Button, Space } from "antd";

function IndexPage(props) {

const {

username,

count,

addCount,

decCount,

addCountAsync,

minusCountAsync,

} = props;

return (

Yay! Welcome to dva!

{username}

{count}

);

}

IndexPage.defaultProps = {

username: "admin",

count: 10,

};

IndexPage.propTypes = {

username: PropTypes.string,

count: PropTypes.number,

};

const matStateToProps = (state) => {

return {

count: state.products.count,

};

};

const mapDispatchToprops = (dispatch) => {

return {

addCount: () => dispatch({ type: "products/addCount" }),

decCount: () => dispatch({ type: "products/minusCount" }),

addCountAsync: () => dispatch({ type: "products/addCountAsync" }),

minusCountAsync: () => dispatch({ type: "products/minusCountAsync" }),

};

};

export default connect(matStateToProps, mapDispatchToprops)(IndexPage);

models/products.js的逻辑

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

export default {

namespace: "products",

state: {

count: 0,

lists: [

{ name: "dva", id: 1 },

{ name: "antd", id: 2 },

],

},

// 同步更新的方法

reducers: {

delete(state, { id }) {

return {

...state,

lists: state.lists.filter((item) => item.id !== id),

};

},

addCount(state) {

return { ...state, count: state.count + 1 };

},

minusCount(state) {

return { ...state, count: state.count - 1 };

},

},

effects: {

// *addCountAsync(action, effects) {

// const { put, select, call } = effects;

// const data = yield select();

// console.log("我被点击了");

// yield call(delay, 2000);

// yield put({ type: "addCount" });

// },

// 设置不同类型的监听器,监听器类型有takeLatest, takeEvery, throttle, debounce

addCountAsync: [

function* (action, effects) {

const { put, call } = effects;

yield call(delay, 2000);

yield put({ type: "addCount" });

},

{

type: "takeLatest",

},

],

*minusCountAsync(action, effects) {

const { put, call } = effects;

yield call(delay, 2000);

yield put({ type: "minusCount" });

},

},

};

**注意:**effects里面的getor方法默认的监听模式是takeEvery模式,也就是每次出发都会见听到,如下图

如果我们要更改模式,getor方法就要改写成如下

之前的,默认是takeEvery

*addCountAsync(action, effects) {

const { put, select, call } = effects;

const data = yield select();

console.log("我被点击了");

yield call(delay, 2000);

yield put({ type: "addCount" });

},

特定的监听模式

addCountAsync: [

function* (action, effects) {

const { put, call } = effects;

yield call(delay, 2000);

yield put({ type: "addCount" });

},

{

type: "takeLatest",

},

]

是不是很简单了,直接简化了之前单独引入三个工具库的代码,操作方便不少。

附上第二个实例的效果及代码

routes/Products .js

import React from "react";

import { connect } from "dva";

import ProductList from "../components/ProductList";

const Products = (props) => {

const { products, deleteProduct } = props;

return (

<>

List of Products

);

};

const mapStateToProps = (state) => {

return {

products: state.products.lists,

};

};

const mapDispatchToProps = (dispatch) => {

return {

deleteProduct: (id) => {

dispatch({ type: "products/delete", id });

},

};

};

export default connect(mapStateToProps, mapDispatchToProps)(Products);

components/ProductList .js

import React from "react";

import PropTypes from "prop-types";

import { Table, Popconfirm, Button } from "antd";

const ProductList = ({ onDelete, products }) => {

const columns = [

{

title: "Name",

dataIndex: "name",

},

{

title: "Actions",

render: (text, record) => {

return (

onDelete(record.id)}>

);

},

},

];

return

;

};

ProductList.defaultProps = {

products: [],

};

ProductList.propTypes = {

onDelete: PropTypes.func.isRequired,

products: PropTypes.array.isRequired,

};

export default ProductList;

评论留言