刚刚入门react,通过视频学习,做一个简单的react表格功能实现。功能满足对表格数据进行增删改,数据来源于后端接口。交互也与后端接口进行!

话不多说,直接看效果!

接口设置了30%的概率报错,出现错误多刷新几次。

这是后端接口地址 接口地址

浏览器可以直接看到接口数据

项目的搭建是参照于umi官网的快速上手进行搭建的,想要试试的小伙伴可以先将项目搭建起来!快速上手

我们的项目主要集中在page下的users文件夹中的内容!

在page下新建uses文件夹

新建这几个文件

我们在components文件夹下放的文件的组件,UserModal,为弹出框组件

import {Reducer,Effect,Subscription} from 'umi'
import users from '.';
import {getRemoteList,editRecord,deleteRecord,addRecord} from './service'
import {SingleUserType} from './data.d'export interface UserState{data:SingleUserType[],meta:{total:number;per_page:number;page:number;}
}interface UserModelType{namespace:'users';state:UserState;reducers:{getList:Reducer<UserState>};effects:{getRemote:Effectedit:Effectdelete:Effectadd:Effect};subscriptions:{setup:Subscription;};}
const UserModel: UserModelType = {
// 命名空间,也叫标识名namespace:'users',// 仓库数据初始值state:{data:[],meta:{total:0,per_page:5,page:1,}},// 同步//action相当于是{type,payload}  type:函数名  payload:数据reducers:{getList(state,{payload}){console.log("reducer here")return payload;}},// 异步 返回的是一个viod 只能通过reduces返回数据effects:{// 异步函数前要加**getRemote(action,{put,call}){const data = yield call (getRemoteList)yield put({type:'getList',payload: data  })},*edit({payload:{id,values}},{put,call}){const data = yield call (editRecord,{id,values})yield put({type:'getRemote'})},*delete({payload:{id}},{put,call}){const data = yield call (deleteRecord,{id})yield put({type:'getRemote'})},*add({payload:{values}},{put,call}){const data = yield call (addRecord,{values})yield put({type:'getRemote'})},},// 订阅subscriptions:{setup({dispatch,history}){return  history.listen((location,action)=>{if(location.pathname=='/users'){console.log("subscription here")dispatch({type:'getRemote',});}});}}};// 导出model
export default UserModel;

在users文件夹下index为主页面,data.a为数据类型,model为模块文件,service为交互后端文件

 index.tsx

import React,{ FC, useState} from 'react';
import { Table,  Space,Modal, Button,Popconfirm,Tag } from 'antd';
import ProTable, { TableDropdown ,ProColumns, ActionType} from '@ant-design/pro-table';
import { connect,Dispatch, Loading,UserState } from 'umi';
import UserModal from './compoents/UserModal';
import {getRemoteList} from './service'import {SingleUserType,FormValues} from './data.d'interface UserPageProps{users:UserState,dispatch:Dispatch,userListLoading:boolean,
}const UserListPage:FC<UserPageProps> =({users,dispatch,userListLoading})=>{const [modalVisible,setModalVisible]=useState(false)const [record,setRecord]=useState<SingleUserType|undefined>(undefined)
const columns = [{title: 'ID',dataIndex: 'id',key: 'id',},{title: '姓名',dataIndex: 'name',key: 'name',render:( text :string) => <a>{text}</a>,},{title: '邮箱',dataIndex: 'email',key: 'email',render: ( text :string) => <a>{text}</a>,},{title: '创建时间',dataIndex: 'create_time',key: 'create_time',},{title: '更新时间',dataIndex: 'update_time',key: 'update_time',},{title: '状态',dataIndex: 'status',key: 'status',render:tag=>{let color='#87d068'if(tag!==1){color = tag == 2 ? '#108ee9' : 'green'} else{color='#f50'}return <Tag color={color} key={tag}>状态:{tag}</Tag>     }},{title: '操作',key: 'action',render: (text:string,record:SingleUserType) => (<Space size="middle"><a onClick={()=>{editHandler(record)}}>编辑</a><Popconfirmtitle="确定要删除这条信息吗?"onConfirm={()=>{confirm(record)}}okText="Yes"cancelText="No"><a href="#">删除</a></Popconfirm></Space>),},
];const editHandler=(record:SingleUserType)=>{   console.log(record)setModalVisible(true);setRecord(record);
}
const closeHandeler=()=>{setModalVisible(false)
}
// 编辑确认
const onFinish = (values:FormValues) => {let id =0if(record){id=record.id;}if(id){console.log('edit')dispatch({type:'users/edit',payload:{id,values}})
}
else{console.log('add')dispatch({type:'users/add',payload:{values}})
}setModalVisible(false)
};
// 删除确定
const confirm=(record:SingleUserType)=>{const id=record.id
dispatch({type:'users/delete',payload:{id}
})}
const addHandler=()=>{setModalVisible(true)setRecord(undefined)
}
const requestHandler= async ({pageSize,current})=>{console.log(pageSize,current)const users=await getRemoteList();return {data:users.data,success:true,total:users.meta.total,}}return(<div className='list-table'><Button type="primary" onClick={addHandler}>添加</Button><ProTable columns={columns} dataSource={users.data} rowKey='id' loading={userListLoading} request={requestHandler}search={false}/><UserModal visible={modalVisible} closeHandeler={closeHandeler} record={record} onFinish={onFinish}></UserModal></div>)
};
const mapStateToProps = ({users,loading}:{users:UserState,loading:Loading})=>{console.log(loading)return{users,userListLoading:loading.models.users,}
}export default connect(mapStateToProps)(UserListPage)

data.d.ts

export interface SingleUserType{"id": number,"name": string,"email": string ,"create_time": string ,"update_time": string,"status": number
}
export interface FormValues{[name:string]:any;}

model.ts

import {Reducer,Effect,Subscription} from 'umi'
import users from '.';
import {getRemoteList,editRecord,deleteRecord,addRecord} from './service'
import {SingleUserType} from './data.d'export interface UserState{data:SingleUserType[],meta:{total:number;per_page:number;page:number;}
}interface UserModelType{namespace:'users';state:UserState;reducers:{getList:Reducer<UserState>};effects:{getRemote:Effectedit:Effectdelete:Effectadd:Effect};subscriptions:{setup:Subscription;};}
const UserModel: UserModelType = {
// 命名空间,也叫标识名namespace:'users',// 仓库数据初始值state:{data:[],meta:{total:0,per_page:5,page:1,}},// 同步//action相当于是{type,payload}  type:函数名  payload:数据reducers:{getList(state,{payload}){console.log("reducer here")return payload;}},// 异步 返回的是一个viod 只能通过reduces返回数据effects:{// 异步函数前要加**getRemote(action,{put,call}){const data = yield call (getRemoteList)yield put({type:'getList',payload: data  })},*edit({payload:{id,values}},{put,call}){const data = yield call (editRecord,{id,values})yield put({type:'getRemote'})},*delete({payload:{id}},{put,call}){const data = yield call (deleteRecord,{id})yield put({type:'getRemote'})},*add({payload:{values}},{put,call}){const data = yield call (addRecord,{values})yield put({type:'getRemote'})},},// 订阅subscriptions:{setup({dispatch,history}){return  history.listen((location,action)=>{if(location.pathname=='/users'){console.log("subscription here")dispatch({type:'getRemote',});}});}}};// 导出model
export default UserModel;

service.ts

import { response } from "@umijs/deps/compiled/express";
import { request } from "umi"
import { message } from 'antd';
import { FormValues } from "./data";
export const getRemoteList =async () => {return request('/api/users',{method:'get',}).then(function(response){console.log("update ok")return response}).catch(function(error){console.log(error);})
}
export const editRecord =async ({id,values}:{id:number,values:FormValues}) => {return request(`/api/users/${id}`,{method:'put',data:values}).then(function(response){message.success('修改成功!');}).catch(function(error){message.error('修改失败!');})
}
export const deleteRecord =async ({id}:{id:number}) => {return request(`/api/users/${id}`,{method:'delete',}).then(function(response){message.success('删除成功!');}).catch(function(error){message.error('删除失败!');})
}
export const addRecord =async ({values}:{values:FormValues}) => {return request(`/api/users/`,{method:'post',data:values}).then(function(response){message.success('添加成功!');}).catch(function(error){message.error('添加失败!');})
}

其中路由配置了代理,可以参考我上一篇发布的文章Umi-Dva配置代理,解决跨域问题_我要当前端工程师的博客-CSDN博客

关于构建umi+dva+ant react项目 附源码相关推荐

  1. 基于SSM实现的网上手机商城项目(附源码)

    基于Spring+Spring MVC+MyBatis+Layui框架 项目完整源码下载 https://download.csdn.net/download/DeepLearning_/873271 ...

  2. 全网首发!精选32个最新Python实战项目(附源码),拿走就用!

    Python是目前最好的编程语言之一.由于其可读性和对初学者的友好性,已被广泛使用.那么要想学会并掌握Python,可以实战的练习项目是必不可少的.接下来,我将给大家介绍32个非常实用的Python项 ...

  3. 【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码

    前言 1.街霸游戏 1.1 KO街霸 程序完整源码 程序的输出界面 1.2 春丽VS巴洛克 参考源码 2.猜谜游戏 2.1简单的猜数字游戏 项目要求 参考源码 2.2 进阶的猜姓名游戏 项目要求 参考 ...

  4. Docker Compose部署项目到容器-基于Tomcat和mysql的商城项目(附源码和sql下载)

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  5. 一个炫酷的二维码生成项目附源码

    前阵子打算换一个炫酷的公众号二维码,无奈市面上很多的二维码修改器都不尽人意. 草料二维码也挺炫酷的,但是也没有满意的效果. 于是又去万能的github逛了一下,终于找到了一款开源的二维码修改器. 这个 ...

  6. 亲手撸了一个SpringBoot+Vue的企业级项目(附源码)

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 简介 SpringBoot和Vue,前后端分离,我们开源一套漂亮的代码和一套整洁的代码规范,让大家在这浮躁的代码世界里感受到一股把代码写好 ...

  7. 我的个人博客项目(附源码)

    我的个人博客项目 文章目录 我的个人博客项目 前言 一.实现登录功能 二.数据存储与JDBC连接 三.实现新增博客 四.实现修改博客 五.实现删除博客 前言   在长达1个月的设计制作过程中,遇到了很 ...

  8. 模仿CSDN黑暗帝国动态背景的vue项目(附源码)

    开发工具:Webstorm 技术栈:vue.html.canvas 实现效果(其实这里面的是动态变换的,只是没有截成GIF动图): 实现步骤: (1)在这里的项目我是用VueCli3脚手架进行搭建的. ...

  9. 【C语言】游戏开发:天天酷跑丨完美练手项目 [附源码]

    目录 一.项目说明: 二.项目作用 三.项目技术要求 四.库.宏.主函数说明 五.项目实现 5.1游戏背景的实现 5.2实现Hero奔跑 5.3 实现Hero跳跃 5.4 优化帧等待 5.6使用结构体 ...

最新文章

  1. JAVA SE学习day_08:TCP通信、多线程(并联)
  2. 接口中可以有静态方法吗?
  3. 从 Windows 切换到 Linux?看这篇就够了!
  4. mysql自动编号步进值_MySQL-自动编号
  5. 对Bootloader(引导加载程序)的几点理解
  6. gif透明背景动画_常用GIF动图制作工具,抖音里面的动图都是这些工具做出来的...
  7. 简单易用的baidutemplate模板的使用
  8. Azure上用API成功创建Lambda Function的截图
  9. Java生鲜电商平台-统一异常处理及架构实战
  10. D3.js系列——布局:饼状图和力导向图
  11. C# textBox框实现输入像百度搜索出现下拉列表的格式
  12. Codeforces 448 D. Multiplication Table
  13. Word转pdf方法小结
  14. 安川西格玛7驱动器手册_安川伺服驱动说明书7.pdf
  15. S5P4418 Android实时时钟框架介绍
  16. Mysql设置自动更新时间
  17. telnet控制路由器交换机与微信公众平台
  18. WINUSB STM32移植参考
  19. 刀片服务器如何选择操作系统,刀片服务器如何选择操作系统?
  20. 转:jsp内置对象中page与pageContext与el内置对象pageScope与pageContext区别

热门文章

  1. 【转载】使用Pytorch进行图像分类,AI challenger 农作物病害分类竞赛源码解读
  2. 运行systeminfo时出现闪退现象
  3. Input标签type属性
  4. 阿里为什么总mysql_为什么部署在阿里云上 MySQL 老是因为内存而挂掉,不是个例....
  5. iphone手机safari浏览器访问网站滚动条不显示问题解决办法
  6. 计算机显示器的三原色是,显示器参数看不懂?看完你就明白啦!
  7. 数据库 连接(自然连接,内连接,外连接)
  8. 人工智能数学课高等数学线性微积分数学教程笔记(1. 数学内容概述)
  9. 微信公众号留言功能怎么开通权限?
  10. IKAnalyzer中文分词分析内容目录