Chapter 6 React UI
1. Popular open source React UI component library
1. material-ui(foreign)
- Official website: http://www.material-ui.com/#/
- github: https://github.com/callemall/material-ui
2. ant-design (domestic Ant Financial)
- Official website: https://ant.design/index-cn
- Github: https://github.com/ant-design/ant-design/
- Use: npm install antd
2. Code
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
Basic use of 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>
);
}
}
Chapter 7 redux
1. Understanding redux
1. Study documents
- English documentation: https://redux.js.org/
- Chinese document: http://www.redux.org.cn/
- Github: https://github.com/reactjs/redux
2. What is redux?
- redux is a JS library specifically used for state management (not a react plug-in library).
- It can be used in react, angular, vue and other projects, but it is basically used with react.
- Function: Centrally manage the state shared by multiple components in react applications.
3. When do you need to use redux?
- The status of a certain component needs to be available (shared) to other components at any time.
- One component needs to change the state of another component (communication).
- The general principle: If you can’t use it, don’t use it. If it’s difficult to use it, consider using it.
4. redux workflow
2. Three core concepts of redux
1. action
- object of action
- Contains 2 attributes
- type: identification attribute, value is a string, unique, required attribute
- data: data attribute, value type is arbitrary, optional attribute
- Example: { type: 'ADD_STUDENT',data:{name: 'tom',age:18} }
2. reducer
- Used for initialization state and processing state.
- During processing, a pure function of new state is generated based on the old state and action .
3. store
- An object that connects state, action, and reducer
- How to get this object?
- import {createStore} from ‘redux’
- import reducer from ‘./reducers’
- const store = createStore(reducer)
- What is the function of this object?
- getState(): get state
- dispatch(action): dispatch action, trigger reducer call, generate new state
- subscribe(listener): Register for listening, automatically called when a new state is generated
3. Redux core API
1. createstore()
- Function: Create a store object containing the specified reducer
2. store object
- Function: The core management object of the redux library
- It maintains internally:
- core methods
- getState()
- dispatch(action)
- subscribe(listener)
- Specific coding
- store.getState()
- store.dispatch({type:‘INCREMENT’, number})
- store.subscribe(render)
3. applyMiddleware()
- Function: Redux-based middleware (plug-in library) for applications
4. combineReducers()
- Function: Combine multiple reducer functions
4. Use redux to write applications
1. Effect
2. Pure react version
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>
<button onClick={
this.increment}>+</button>
<button onClick={
this.decrement}>-</button>
<button onClick={
this.incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={
this.incrementAsync}>异步加</button>
</div>
);
}
}
3. redux lite version
- Installation: npm install 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>
<button onClick={
this.increment}>+</button>
<button onClick={
this.decrement}>-</button>
<button onClick={
this.incrementIfOdd}>当前求和为奇数再加</button>
<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 Summary
(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 full version
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>
<button onClick={
this.increment}>+</button>
<button onClick={
this.decrement}>-</button>
<button onClick={
this.incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={
this.incrementAsync}>异步加</button>
</div>
);
}
}
4.6 Summary
新增文件:
1.count_action.js 专门用于创建action对象
2.constant.js 放置容易写错的type值