react dispatch_手把手教你创建Ant Design Pro的React项目

介绍

主要是使用 ReactTypeScript 以及 Ant Design Pro 开发中后台项目,那么就会有人问“可不可开发前台”,回答是“可以”;Ant Design 是蚂蚁金服的UI框架,发展历程可以说是从 saga-redux -> dva -> umi -> ant design ,说 ant designreact 的最佳实践确实是名副其实;其中我最喜欢或者说是 dva 最显著的地方就是修缮了 redux 的不足之处。

搭建

  1. 安装 cnpm,yarn,tyarn
npm i -g cnpm --registry=https://registry.npm.taobao.org
cnpm i yarn -g
yarn global add tyarn

2. Ant Design Pro 立足于 umijs 、dva,需要安装 umi

yarn global add umi

3. 创建 Ant Design Pro 项目(先创建test文件夹)

mkdir test
cd test
yarn create umi  (这里选择 ant design pro -> typescript -> simple)
tyarn
yarn start

442892ea257da161dab34c8e22b3a423.png
+ config
    - config.ts  路由设计
    - proxy.ts   代理(打包后无效)
+ mock           模拟数据
+ src
    - assets     放一些静态资源文件(png,svg等)
    - component  主要放全局组件
    - layouts    权限、token获取
    - models     详细内容见dva,换言之是redux (interface、数据交互)
    - pages      页面
    - serives    请求(get,post)
    - utils      放一些公用方法

/* 以上为本人对ant design pro各个模块的理解,不足之处还请指教 */

dc0e588aad9510c5b1319b4033470761.png

举个栗子(dva)

TypeScript 最突出的就是类型注解,其目的就是减少对类型的试错,从而达到优化
/** 
 * 假设你现在要做一个博客网站,现在你要搭建的是你的博客首页
 * 1. 现在你的 page 已经写好了(src/home/index.tsx和src/home/index.less)
 * 2. 你的后端接口也已经写好了,提供的接口就是 home (GET)
 * 3. 你也已经在 config/proxy.ts 中写好了代理,代理名 api
 **/

现在你需要创建一个 src/services/home.ts 去对接后台的接口。

import request from '@/utils/request'    // ant design pro 自带(无须修改,每次请求自动携带 token)

interface HomeParams{
   currentPage: number;
   pageSize: number;
}

export async function queryGetMyHomeData(payload: HomeParams){
    return request( `/api/home` ,{
        method: 'GET',
        params: {
            // 填写你需要传给后端的字段
            ... payload,
        }
        /**
         * 如果是 POST 请求,请将 params 修改成 data
         **/
    })
}

接下来,你需要创建一个 src/models/home.ts 去调用上面那个接口 (详细教程看 dva),我这是临时起意边想边写的(俗称瞎编乱造)。

import { queryGetMyHomeData } from '@/services/home'
import { Effect, Reducer } from 'umi';

export interface DataItem{
    // 暂且假设后端回给你的只有(ID、博客标题、发布日期(毫秒数)、摘要)
    id: number;
    title: string;
    createdDate: number; 
    brief: string;
}

// state 对应的类型(接口)
export interface HomeState{
    currentPage: number;
    data: Array<DataItem>;
}

export interface HomeModelType{
    namespace: string;    // 说好听点叫做 "命名空间"
    state: HomeState;     // 就是 state
    effects: {            // effects 里面的可以调用 reducers 里面的
        getData: Effect,
        changePage: Effect,
    };
    reducers: {
        setData: Reducer<HomeState>,
        setPage: Reducer<HomeState>,
    };
}

const HomeModel = {
    namespace: 'home',
    state: {
        currentPage: 1,
        data: [],
    },
    effects: {
        *getData( { payload }, { call, put }){
            const res = yield call( queryGetMyHomeData, payload );  // payload 要对应 queryGetMyHomeData 的形参,否则另当别论
            const arr = Array.isArray(res.data) ? res.data : [];    // 我这里假设返回的 res.data 就是我们所需要的数据
            yield put({    // 将数据放到 state 里面
                type: 'setData',
                payload: {
                    data: arr,
                }
            })
        },
        *changePage( { payload }, { call, put }){
            yield put({ type: 'setPage', payload });
            // yield take( 'setPage/@@end' );    // 阻塞等待完成再往下执行,当然我们这里并不存在一步造成的问题
            yield put({ type: 'getData', payload });
        },
    },
    reducers: {
        setData( state, { payload } ){
            return {
                ... state,
                ... payload,
            }
        },
        setPage( state, { payload } ){
            return {
                ... state,
                ... payload,
            }
        },
    }
}

export default HomeModel;

src/pages/home/index.tsxconnect HomeModel

import React, { useEffect } from 'react';
import { connect, Dispatch } from 'umi';
import { HomeState } from '@/models/home'

interface HomeProps{
    dispatch: Dispatch;
    home: HomeState;
}

const Home: React.FC<HomeProps> = (props) => {
    // 拿到的内容可以直接使用
    const { 
        dispatch,
        home: {
            currentPage, 
            data,
        }
    } = props;

    // 获取数据,或者说是初始化数据
    useEffect(() => {
        dispatch({
            type: 'home/getData' ,
            payload: {
                currentPage,
                pageSize: 8,
            }
        })
    }, []);

    // 页码改变事件
    function pageChange(page){
        /**
         * page的修改是两个操作
         * 1. 修改 page
         * 2. 获取数据
         * 3. 如果面临异步问题(我们这里用阻塞)-- 这里不存在此问题
         **/
        dispatch({
            type: 'home/changePage' ,
            payload: {
                currentPage: page,
                pageSize: 8,
            }
        })
    }

    return (
        // ... 这里我就省略不写了
    );
}

export default connect (home: HomeState => home)(Home);
还有一点要 提醒,effects 里面的 和 reducers 里面的函数名不能一样。
有关于 Dva 对 Redux 的修改,见下图

ea0ec94c2cd4e2081dddddd852299b4c.png
图片来源:Dva 官方文档

谈谈近期

近期有不少人在喷尤雨溪,说他怎么怎么,我也是特别的懊恼这些喷子,Vue是开源不收费的,而且尤雨溪确实很强,我自认为他是我们国内前端领域最牛逼的人之一,没有什么好喷,而且人家实力就摆在那里。


300d89b553b1fad96c38180534ef0108.png
叄贰壹的博客_CSDN博客-渗透测试,java基础,leetcode领域博主​blog.csdn.net
5e04d41ffc15ed6a1301ea8d49a23d06.png
带只拖鞋去流浪 - 简书​www.jianshu.com
99e7810be633e7c6febe5e688f3ae63c.png

WARNING

商业转载请联系本人,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值