第六章 React UI
一、流行的开源 React UI 组件库
1. material-ui(国外)
官网: http://www.material-ui.com/#/ github: https://github.com/callemall/material-ui
2. ant-design(国内蚂蚁金服)
官网: https://ant.design/index-cn Github: https://github.com/ant-design/ant-design/ 使用:npm install antd
二、代码
import React from "react" ;
import ReactDOM from "react-dom" ;
import App from "./App" ;
ReactDOM. render ( < App / > , document. getElementById ( "root" ) ) ;
antd 的基本使用
import React, { Component } from "react" ;
import { Button, DatePicker } from "antd" ;
import {
WechatOutlined,
WeiboOutlined,
SearchOutlined,
} from "@ant-design/icons" ;
const { RangePicker } = DatePicker;
export default class App extends Component {
render ( ) {
return (
< div>
App... .
< button> 点我< / button>
< Button type= "primary" > Button1< / Button>
< Button> Button2< / Button>
< Button type= "link" > Button3< / Button>
< Button type= "primary" icon= { < SearchOutlined / > } >
Search
< / Button>
< WechatOutlined / >
< WeiboOutlined / >
< DatePicker / >
< RangePicker / >
< / div>
) ;
}
}
第七章 redux
一、redux 理解
1. 学习文档
英文文档: https://redux.js.org/ 中文文档: http://www.redux.org.cn/ Github: https://github.com/reactjs/redux
2. redux 是什么
redux 是一个专门用于做状态管理 的 JS 库(不是 react 插件库)。 它可以用在 react, angular, vue 等项目中, 但基本与 react 配合使用。 作用: 集中式管理 react 应用中多个组件共享 的状态。
3. 什么情况下需要使用 redux
某个组件的状态,需要让其他组件可以随时拿到(共享)。 一个组件需要改变另一个组件的状态(通信)。 总体原则:能不用就不用, 如果不用比较吃力才考虑使用。
4. redux 工作流程
二、redux 的三个核心概念
1. action
动作的对象 包含 2 个属性
type:标识属性, 值为字符串, 唯一, 必要属性 data:数据属性, 值类型任意, 可选属性 例子:{ type: ‘ADD_STUDENT’,data:{name: ‘tom’,age:18} }
2. reducer
用于初始化状态、加工状态。 加工时,根据旧的 state 和 action,产生新的 state 的纯函数 。
3. store
将 state、action、reducer 联系在一起的对象 如何得到此对象?
import {createStore} from ‘redux’ import reducer from ‘./reducers’ const store = createStore(reducer) 此对象的功能?
getState(): 得到 state dispatch(action): 分发 action, 触发 reducer 调用, 产生新的 state subscribe(listener): 注册监听, 当产生了新的 state 时, 自动调用
三、redux 的核心 API
1. createstore()
作用:创建包含指定 reducer 的 store 对象
2. store 对象
作用: redux 库最核心的管理对象 它内部维护着:
核心方法
getState() dispatch(action) subscribe(listener) 具体编码
store.getState() store.dispatch({type:‘INCREMENT’, number}) store.subscribe(render)
3. applyMiddleware()
4. combineReducers()
四、使用 redux 编写应用
1. 效果
2. 纯 react 版
2.1 App
import React, { Component } from "react" ;
import Count from "./components/Count" ;
export default class App extends Component {
render ( ) {
return (
< div>
< Count / >
< / div>
) ;
}
}
2.2 Count
import React, { Component } from "react" ;
export default class Count extends Component {
state = { count : 0 } ;
increment = ( ) => {
const { value } = this . selectNumber;
const { count } = this . state;
this . setState ( { count : count + value * 1 } ) ;
} ;
decrement = ( ) => {
const { value } = this . selectNumber;
const { count } = this . state;
this . setState ( { count : count - value * 1 } ) ;
} ;
incrementIfOdd = ( ) => {
const { value } = this . selectNumber;
const { count } = this . state;
if ( count % 2 !== 0 ) {
this . setState ( { count : count + value * 1 } ) ;
}
} ;
incrementAsync = ( ) => {
const { value } = this . selectNumber;
const { count } = this . state;
setTimeout ( ( ) => {
this . setState ( { count : count + value * 1 } ) ;
} , 500 ) ;
} ;
render ( ) {
return (
< div>
< h1> 当前求和为:{ this . state. count} < / h1>
< select ref= { ( c ) => ( this . selectNumber = c) } >
< option value= "1" > 1 < / option>
< option value= "2" > 2 < / option>
< option value= "3" > 3 < / option>
< / select>
& nbsp;
< button onClick= { this . increment} > + < / button> & nbsp;
< button onClick= { this . decrement} > - < / button> & nbsp;
< button onClick= { this . incrementIfOdd} > 当前求和为奇数再加< / button> & nbsp;
< button onClick= { this . incrementAsync} > 异步加< / button>
< / div>
) ;
}
}
3. redux 精简版
3.1 store
import { createStore } from "redux" ;
import countReducer from "./count_reducer" ;
export default createStore ( countReducer) ;
3.2 count_reducer
const initState = 0 ;
export default function countReducer ( preState = initState, action ) {
const { type, data } = action;
switch ( type) {
case "increment" :
return preState + data;
case "decrement" :
return preState - data;
default :
return preState;
}
}
3.3 Count
import React, { Component } from "react" ;
import store from "../../redux/store" ;
export default class Count extends Component {
increment = ( ) => {
const { value } = this . selectNumber;
store. dispatch ( { type : "increment" , data : value * 1 } ) ;
} ;
decrement = ( ) => {
const { value } = this . selectNumber;
store. dispatch ( { type : "decrement" , data : value * 1 } ) ;
} ;
incrementIfOdd = ( ) => {
const { value } = this . selectNumber;
const count = store. getState ( ) ;
if ( count % 2 !== 0 ) {
store. dispatch ( { type : "increment" , data : value * 1 } ) ;
}
} ;
incrementAsync = ( ) => {
const { value } = this . selectNumber;
setTimeout ( ( ) => {
store. dispatch ( { type : "increment" , data : value * 1 } ) ;
} , 500 ) ;
} ;
render ( ) {
return (
< div>
< h1> 当前求和为:{ store. getState ( ) } < / h1>
< select ref= { ( c ) => ( this . selectNumber = c) } >
< option value= "1" > 1 < / option>
< option value= "2" > 2 < / option>
< option value= "3" > 3 < / option>
< / select>
& nbsp;
< button onClick= { this . increment} > + < / button> & nbsp;
< button onClick= { this . decrement} > - < / button> & nbsp;
< button onClick= { this . incrementIfOdd} > 当前求和为奇数再加< / button> & nbsp;
< button onClick= { this . incrementAsync} > 异步加< / button>
< / div>
) ;
}
}
3.4 index
import React from "react" ;
import ReactDOM from "react-dom" ;
import App from "./App" ;
import store from "./redux/store" ;
ReactDOM. render ( < App / > , document. getElementById ( "root" ) ) ;
store. subscribe ( ( ) => {
ReactDOM. render ( < App / > , document. getElementById ( "root" ) ) ;
} ) ;
3.5 总结
( 1 ) .去除Count组件自身的状态
( 2 ) .src下建立:
-redux
-store.js
-count_reducer.js
( 3 ) .store.js:
1 ) .引入redux中的createStore函数,创建一个store
2 ) .createStore调用时要传入一个为其服务的reducer
3 ) .记得暴露store对象
( 4 ) .count_reducer.js:
1 ) .reducer的本质是一个函数,接收:preState,action,返回加工后的状态
2 ) .reducer有两个作用:初始化状态,加工状态
3 ) .reducer被第一次调用时,是store自动触发的,
传递的preState是undefined,
传递的action是:{ type:'@@REDUX/INIT_a.2.b.4}
( 5 ) .在index.js中监测store中状态的改变,一旦发生改变重新渲染< App/>
备注:redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写。
4. redux 完整版
4.1 store
import { createStore } from "redux" ;
import countReducer from "./count_reducer" ;
export default createStore ( countReducer) ;
4.2 constant
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
4.3 count_action
import { INCREMENT , DECREMENT } from "./constant" ;
export const createIncrementAction = ( data ) => ( { type : INCREMENT , data } ) ;
export const createDecrementAction = ( data ) => ( { type : DECREMENT , data } ) ;
4.4 count_reducer
import { INCREMENT , DECREMENT } from './constant'
const initState = 0 ;
export default function countReducer ( preState = initState, action ) {
const { type, data } = action;
switch ( type) {
case INCREMENT :
return preState + data;
case DECREMENT :
return preState - data;
default :
return preState;
}
}
4.5 Count
import React, { Component } from "react" ;
import store from "../../redux/store" ;
import { createDecrementAction, createIncrementAction} from '../../redux/count_action'
export default class Count extends Component {
increment = ( ) => {
const { value } = this . selectNumber;
store. dispatch ( createIncrementAction ( value* 1 ) ) ;
} ;
decrement = ( ) => {
const { value } = this . selectNumber;
store. dispatch ( createDecrementAction ( value* 1 ) ) ;
} ;
incrementIfOdd = ( ) => {
const { value } = this . selectNumber;
const count = store. getState ( ) ;
if ( count % 2 !== 0 ) {
store. dispatch ( createIncrementAction ( value* 1 ) ) ;
}
} ;
incrementAsync = ( ) => {
const { value } = this . selectNumber;
setTimeout ( ( ) => {
store. dispatch ( createIncrementAction ( value* 1 ) ) ;
} , 500 ) ;
} ;
render ( ) {
return (
< div>
< h1> 当前求和为:{ store. getState ( ) } < / h1>
< select ref= { ( c ) => ( this . selectNumber = c) } >
< option value= "1" > 1 < / option>
< option value= "2" > 2 < / option>
< option value= "3" > 3 < / option>
< / select>
& nbsp;
< button onClick= { this . increment} > + < / button> & nbsp;
< button onClick= { this . decrement} > - < / button> & nbsp;
< button onClick= { this . incrementIfOdd} > 当前求和为奇数再加< / button> & nbsp;
< button onClick= { this . incrementAsync} > 异步加< / button>
< / div>
) ;
}
}
4.6 总结
新增文件:
1 .count_action.js 专门用于创建action对象
2 .constant.js 放置容易写错的type值