1.Ant Design介绍和环境初始化

Ant Design是一套面向企业级开发的UI框架,视觉和动效作的很好。阿里开源的一套UI框架,它不只支持React,还有ngVue的版本,我认为不论你的前端框架用什么,Ant Design都是一个不错的选择。习惯性把AntDesign简称为antd

官网地址:https://ant.design/index-cn

2.项目初始化

#安装脚手架工具
cnpm install -g create-react-app
create-react-app demo05-redux
cd demo05-redux
yarn start

3.生成基本代码结构

删除src下所有文件,创建index.js。

import React from "react";
import ReactDOM from 'react-dom'
import App from './App'ReactDOM.render(<App/>,document.getElementById('root'))

创建App.js。

import React, {Component} from "react";class App extends Component {render() {return (<div>Hello World</div>)}
}export default App;

3.安装Ant Design

cnpm install antd --save
#或
yarn add antd

4.使用Ant Design制作基础UI界面

引入CSS样式

import 'antd/dist/antd.css'

编写Input框和Button按钮

import React, {Component} from "react";
import 'antd/dist/antd.css'
import {Input,Button} from "antd";//需要什么组件,引入什么组件class App extends Component {render() {return (<div><div><Input placeholder={'karma'} style={{ width:'250px'}}/><Button type="primary">添加</Button></div></div>)}
}export default App;

添加List列表,首先我们需要在class外声明一个data数组

const data=['test1','test2','test3'
]

再在App.js中,引入List组件。

import {Input,Button,List} from "antd";//需要什么组件,引入什么组件

添加List组件。

import React, {Component} from "react";
import 'antd/dist/antd.css'
import {Input, Button, List} from "antd";//需要什么,引入什么const data = ['test1','test2','test3'
]class App extends Component {render() {return (<div><div><Input placeholder={'karma'} style={{width: '250px'}}/><Button type="primary">添加</Button></div>{/*主要代码*/}<div><ListbordereddataSource={data}renderItem={item => (<List.Item>{item}</List.Item>)}></List></div>{/*主要代码*/}</div>)}
}export default App;

5.创建Redux中的仓库-store和reducer

首先需要先安装Redux。

cnpm install --save redux

再在src目录下创建store目录,在store目录下创建index.js。

import { createStore } from 'redux'  // 引入createStore方法
const store = createStore()          // 创建数据存储仓库
export default store                 //暴露出去

再创建reducer.js在store目录下。

const defaultState = {}  //默认数据
export default (state = defaultState,action)=>{  //就是一个方法函数//state: 是整个项目中需要管理的数据信息,这里我们没有什么数据,所以用默认空的来表示。return state
}

最后在store/index.js中引入reducer,再将reducer以参数的形式传递给createStore方法。

import {createStore} from "redux";
import reducer from "./reducer";
const store =createStore(reducer);
export default store;

仓库storereducer都创建好了,可以初始化下App.js中的数据了,在reducer.js文件的defaultState对象中,加入两个属性:inputValuelist

const defaultState = {inputValue: 'karma',list: ['test1','test2','test3']
}  //默认数据

让App.js组件获取到store中初始化的数据,在组件引入store。

import store from './store'
#或者
import store from './store/index'

再在组件的构造函数中获取到数据,将它赋值给组件的state,最后再将数据进行渲染。

import React, {Component} from "react";
import 'antd/dist/antd.css'
import {Input, Button, List} from "antd";//需要什么,引入什么
import store from "./store";class App extends Component {// 主要代码constructor(props) {super(props);this.state=store.getState();}// 主要代码render() {return (<div><div><Input placeholder={'karma'} style={{width: '250px'}}/><Button type="primary">添加</Button></div><div>{/*主要代码*/}<ListbordereddataSource={this.state.list}renderItem={item => (<List.Item>{item}</List.Item>)}></List>{/*主要代码*/}</div></div>)}
}
export default App;

6.通过Input体验Redux的流程

给Input添加onChange时间,并在构造函数中进行bind绑定。

##创建inputChange方法
changeInputValue(e){console.log(e.target.value)
}##Input添加onChange事件,并再添加一个Input框,用来获取到第一个Input值的变化情况
<Input placeholder={'karma'} style={{width: '250px'}} onChange={this.inputChange}/>
<Input value={this.state.inputValue} style={{width: '250px'}} onChange={this.inputChange}/>
##构造函数中,进行绑定
this.inputChange=this.inputChange.bind(this)

在changeInputValue方法中,创建Action交互动作。

inputChange(e) {const action = {type: 'inputChange',##获取到Input框的值value: e.target.value}##通过dispatch传递到store中store.dispatch(action)
}

然后在reducer.js中进行数据改变操作。

export default (state = defaultState, action) => {  //就是一个方法函数//state: 是整个项目中需要管理的数据信息,这里我们没有什么数据,所以用默认的来表示。if (action.type==='inputChange'){//Reducer里只能接收state,不能改变state,所以我们进行深度拷贝let newState=JSON.parse(JSON.stringify(state))//深度拷贝newState.inputValue=action.valuereturn newState}return state
}

记住:Reducer里只能接收state,不能改变state。

接着我们需要使得组件发生更新,我们需要在App组件构造函数中添加store订阅。


constructor(props) {super(props);this.state = store.getState();this.inputChange = this.inputChange.bind(this)// 主要代码this.storeChange = this.storeChange.bind(this)store.subscribe(this.storeChange)// 主要代码
}##并添加storeChange方法,进行重新setState更新组件数据
storeChange() {this.setState(store.getState())
}

然后我们在浏览器第一个Input框中输入值,第二个Input也随着变化。

7.添加Button响应事件

首先我们给Button添加onClick点击事件,并在构造函数中进行绑定。

<Input value={this.state.inputValue} style={{width: '250px'}} onChange={this.inputChange}/>
<Button type="primary" onClick={this.addItem}>添加</Button>##构造函数中添加绑定
this.addItem = this.addItem.bind(this)##添加addItem方法,创建action,并通过dispatch将操作传递给store
addItem() {const action = {type: 'addItem'}store.dispatch(action)
}

然后我们在reducer.js进行list数据添加操作。

export default (state = defaultState, action) => {  //就是一个方法函数//state: 是整个项目中需要管理的数据信息,这里我们没有什么数据,所以用默认的来表示。if (action.type === 'inputChange') {let newState = JSON.parse(JSON.stringify(state))//深度拷贝newState.inputValue = action.valuereturn newState}if (action.type === 'addItem') {let newState = JSON.parse(JSON.stringify(state))//深度拷贝newState.list.push(newState.inputValue)newState.inputValue = ''return newState}return state
}

最后我们就可以点击Button按钮进行List数据添加。

8.通过Redux进行List的删除

首先,我们需要给List子项绑定onClick事件,并传递下标进行绑定。

<ListbordereddataSource={this.state.list}renderItem={(item, index) => (<List.Item onClick={this.itemChange.bind(this, index)}>{item}</List.Item>)}></List>##添加删除方法,将action操作通过dispatch传递到store中deleteItem(index) {const action = {type: 'deleteItem',index}store.dispatch(action)}

再在reducer.js中,进行数据删除操作更新。

if (action.type === 'deleteItem') {let newState = JSON.parse(JSON.stringify(state))//深度拷贝newState.list.splice(action.index, 1)return newState
}

然后在浏览器中,我们就可以点击item子项,进行List数据删除。

9.把Action Type单独创建一个js文件管理

#创建store/actionTypes.js
export const CHANGE_INPUT='changeInput'
export const ADD_INFO='addInfo'
export const DELETE_ITEM='deleteItem'
export const GET_LIST='getList'

引入Action中使用

#actionTypes.js
import {CHANGE_INPUT, ADD_INFO, DELETE_ITEM} from './store/actionTypes'changeInput(e) {const action = {type: CHANGE_INPUT,value: e.target.value}store.dispatch(action)
}clickBtn() {const action = {type: ADD_INFO}store.dispatch(action)
}deleteItem(index) {const action = {type: DELETE_ITEM,index}store.dispatch(action)
}

引入Reducer并进行更改

#reducer.js
import {CHANGE_INPUT, ADD_INFO, DELETE_ITEM} from './actionTypes'if (action.type === CHANGE_INPUT) {let newState = JSON.parse(JSON.stringify(state))//深度拷贝statenewState.inputValue = action.valuereturn newState
}
if (action.type === ADD_INFO) {let newState = JSON.parse(JSON.stringify(state))//深度拷贝statenewState.list.push(newState.inputValue)newState.inputValue = ''return newState
}
if (action.type === DELETE_ITEM) {let newState = JSON.parse(JSON.stringify(state))//深度拷贝statenewState.list.splice(action.index, 1)return newState;
}

10.编写actionCreators.js

为了让action方便统一管理,使得代码更加简洁。

#actionCreators.js
import {CHANGE_INPUT, ADD_INFO, DELETE_ITEM, GET_LIST} from './actionTypes'export const changeInput = (value) => ({type: CHANGE_INPUT,value
})export const clickBtn = () => ({type: ADD_INFO
})export const deleteItem = (index) => ({type: DELETE_ITEM,index
})

在App.js中引入action常量方法

#App.js
import {changeInput, clickBtn, deleteItem} from './store/actionCreators'#方法修改
changeInput(e) {store.dispatch(changeInput(e.target.value))
}clickBtn() {store.dispatch(clickBtn())
}deleteItem(index) {store.dispatch(deleteItem(index))
}

11.Redux所遇到的坑

  • store必须是唯一的,多个store是坚决不允许,只能有一个store空间
  • 只有store能改变自己的内容,Reducer不能改变
  • Reducer必须是纯函数

12.组建UI和业务拆分

拆分UI组件,首先我们先创建一个AppUI.js文件,将App.js中的JSX部分代码复制过来,并引入所需的相关组件

import React, {Component} from "react";
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'
class AppUI extends Component {render() {return (<div style={{margin: '10px'}}><div><Input style={{width: '250px', marginRight: '10px'}}onChange={this.changeInput} value={this.state.inputValue}/><Button type={"primary"} onClick={this.clickBtn}>添加</Button></div><div><ListbordereddataSource={this.state.list}renderItem={(item, index) => (<List.Item onClick={this.deleteItem.bind(this, index)}>{item}</List.Item>)}/></div></div>)}
}export default AppUI;

修改App.js文件

#引入AppUI组件
import AppUI from "./AppUI";#并修改JSX部分代码
render() { return ( <AppUI />);
}
UI组件和业务逻辑组件整合
#App.jsconstructor(props) {super(props);this.state = store.getState();this.changeInput = this.changeInput.bind(this)this.clickBtn = this.clickBtn.bind(this)#需要在constructor(构造函数里)对deleteItem方法进行重新绑定thisthis.deleteItem = this.deleteItem.bind(this)this.storeChange = this.storeChange.bind(this)store.subscribe(this.storeChange)
}
render() {return (<AppUIchangeInput={this.changeInput}inputValue={this.state.inputValue}clickBtn={this.clickBtn}list={this.state.list}deleteItem={this.deleteItem}
/>);
}
#AppUI.js
import React, {Component} from "react";
import {Button, Input, List} from "antd";
import 'antd/dist/antd.css'
class AppUI extends Component {render() {return (<div style={{margin: '10px'}}><div><Input style={{width: '250px', marginRight: '10px'}}onChange={this.props.changeInput} value={this.props.inputValue}/><Button type={"primary"} onClick={this.props.clickBtn}>添加</Button></div><div><ListbordereddataSource={this.props.list}renderItem={(item, index) => (<List.Item onClick={() => this.props.deleteItem(index)}>{item}</List.Item>)}/></div></div>)}
}export default AppUI;

需要注意的是在List组件的删除功能,需要用箭头函数的形式,代替以前方法,并在箭头函数里使用属性的方法,调用出啊你过来的方法。

<ListbordereddataSource={this.props.list}renderItem={(item,index)=>(<List.Item onClick={()=>{this.props.deleteItem(index)}}>{item}</List.Item>)}
/>

13.Redux中的无状态组件

  1. 首先我们不在需要引入React中的{ Component },删除就好。
  2. 然后些一个TodoListUI函数,里边只返回JSX的部分就好,这步可以复制。
  3. 函数传递一个props参数,之后修改里边的所有props,去掉this
import React from "react";
import {Button, Input, List} from "antd";
import 'antd/dist/antd.css'const AppUI = (props) => {return (<div style={{margin: '10px'}}><div><Input style={{width: '250px', marginRight: '10px'}}onChange={props.changeInput} value={props.inputValue}/><Button type={"primary"} onClick={props.clickBtn}>添加</Button></div><div><ListbordereddataSource={props.list}renderItem={(item, index) => (<List.Item onClick={() => props.deleteItem(index)}>{item}</List.Item>)}/></div></div>)
}export default AppUI;

14.Axios异步获取list数据

利用easy-mock模拟数据

https://www.easy-mock.com/mock/5f96cc6134c55d14fda96ea1/example/query#自定义返回数据格式
{"success": true,"data": {"list": ["test1","test2","test3"]}
}

安装并使用Axios

cnpm install --save axios

在App.js中引入axios,并在组件中声明周期函数

import axios from 'axios'#声明周期函数 componentDidMount
componentDidMount(){axios.get('https://www.easy-mock.com/mock/5f96cc6134c55d14fda96ea1/example/query').then((res)=>{console.log(res)})
}

将数据渲染传递给list,首先我们需要在store/actionCreators.js文件中,引入action常量,创建一个新的函数,

#actionTypes.js
export const GET_LIST='getList'#actionCreators.js
import {GET_LIST} from './actionTypes'
export const getList = (list) => ({type: GET_LIST,list
})

然后在App.js中引入函数,并将数据通过store.dispatch传递list值

import {getList} from './store/actionCreators'componentDidMount() {Axios.get('https://www.easy-mock.com/mock/5f96cc6134c55d14fda96ea1/example/query').then((res) => {console.log(res)store.dispatch(getList(res.data.data.list))})
}

最后在reducer.js中将值赋给list

#引入action常量
import {GET_LIST} from './actionTypes'#创建action事件
if (action.type === GET_LIST) {let newState = JSON.parse(JSON.stringify(state))//深度拷贝statecnewState.list=action.listreturn newState;
}

个人博客:Karma‘s Blog
源码地址:传送门

Redux案例-基于Ant Design React相关推荐

  1. React 基于ant design Pro 4 实现的一个分页, 自定义页码颜色

    标题目录 代码 样式 前言 这是在 Ant Design Pro 4 中基于 ant design 的 Pagination 分页组件的基础上开发的. 有这么一个需求, 页码的颜色基于该页是否有差异, ...

  2. 基于Ant Design和jQuery UI的表单设计器

    基于Ant Design 和jQuery UI 的表单设计器 GitHub 地址 概念 Comonent 组件 Layout 布局,一种特殊的Component Component Editor 组件 ...

  3. 基于Ant Design of Vue实现时长组件 duration

    最近遇到一个需求,需要一个输入时长的组件,在经过一番寻找后没有合适的,最终自己动手写一个(实现了v-model双向绑定),记录一下,也给小伙伴们提供一个方便. 本示例基于ant design of v ...

  4. 基于Ant Design UI框架的React项目

    概述 这款基于React开发的UI框架,界面非常简洁美观,在这篇文章中我主要为大家介绍一下如何用Ant开始搭建React项目 详细 代码下载:http://www.demodashi.com/demo ...

  5. 弹窗案例实现(Ant Design + React hooks)

    Ant Design 是React里常用的UI框架 我们选用的是Ant Design 的 Modal 我们可以从Ant Design 官网看到一个基本的弹框大致长这个样子 一个弹框,大概需要弹框名称, ...

  6. Vue 2.x折腾记 - (16) 基于Ant Design Vue 封装一个配置式的表单搜索组件

    前言 这次的后台管理系统项目选型用了Vue来作为主技术栈: 因为前段时间用过React来写过项目(用了antd),感觉棒棒的. 所以这次就排除了Element UI,而采用了Ant Design Vu ...

  7. 基于ant design pro的前后端分离的小型餐馆管理系统

    安装配置 前端 下载代码 antDesignProLearning-front 安装依赖,在命令行输入命令npm install或yarn 官方推荐使用 tyarn 来进行包管理,可以极大地减少 in ...

  8. antd 日期选择框如何提交_基于Ant Design的Modal组件来实现一个可拖拽的React模态框...

    引言 写这篇文章的原因是因为在项目中用到了Antd Design的React组件,当有业务需求需要用到模态框的时候遇到了一些小问题,Antd的模态框Modal组件时不能拖拽的,一般情况下不可拖拽也没什 ...

  9. 极客Go云监工 — 基于Ant Design的Web React实现

    前言 玩客云接口的破解和后端api都已经分析了,那些都是看不见的,而展现在用户面前的是前端的web或者微信的小程序. 由于一开始还不会小程序就先用react写了一个前端,写的比较乱,将就能用,也没有系 ...

最新文章

  1. 12、Struts2表单重复提交
  2. Serverless 解惑——函数计算如何访问 Mongo 数据库
  3. Android studio 使用SVN需要忽略的文件
  4. webpack使用教程
  5. windows 下安装wamp环境
  6. 阿里十年DBA经验产品经理:真的不要再有一起删库跑路事件了
  7. MaxCompute Hash Clustering介绍
  8. 【Mac】Mac键盘实现Home, End, Page UP, Page DOWN
  9. winform布局、控件
  10. 2.吴恩达机器学习课程-作业2-逻辑回归
  11. 规则引擎drools java,spring,spring-boot,drools使用案例
  12. C语言实现可视化,运用EasyX实现拼图+文字解谜+迷宫+猜数游戏
  13. VS2019官方下载地址
  14. 计算机如何添加gust用户,win7系统如何创建安全的Guest账户
  15. 路由器linux+开机启动,路由器里设置FRP开机启动教程
  16. 软件工程——软件总体设计
  17. jarsigner签名APK完整步骤
  18. oracle 10g 与11g的几点常用区别
  19. MD5.js,前端MD5加密
  20. 新闻编辑室第三季/全集The Newsroom迅雷下载

热门文章

  1. 云南旅游最美景点20强最新排名
  2. 凸优化第四章凸优化问题 4.2凸优化
  3. P5278 算术天才⑨与等差数列 题解
  4. html怎么转换内联元素,css怎么将内联元素设成块元素?
  5. 【Java代码的运行过程】 ——每天一点小知识
  6. 游戏出海如何以低成本获取高收益?
  7. 2021 New Year‘s Resolution
  8. 数据结构java实验 刘小晶_数据结构实例解析与实验指导:Java语言描述
  9. 吃透Chisel语言.36.Chisel实战之以FIFO为例(一)——FIFO Buffer和Bubble FIFO的Chisel实现
  10. 远程访问服务器tensorboard