1.redux的使用

核心概念

action

  1. 動作的物件

  2. 包含2個屬性

    type:標識屬性, 值為字串, 唯一, 必要屬性
    data:資料屬性, 值型別任意, 可選屬性
  3. 例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }

reducer

  1. 用於初始化狀態、加工狀態。

  2. 加工時,根據舊的state和action, 產生新的state的純函式

store

  1. 將state、action、reducer聯絡在一起的物件

  2. 如何得到此物件?

    1)   import {createStore} from 'redux'
    
    2)   import reducer from './reducers'
    
    3)   const store = createStore(reducer)
  3. 此物件的功能?

    1)   getState(): 得到state
    
    2)   dispatch(action): 分發action, 觸發reducer呼叫, 產生新的state
    
    3)   subscribe(listener): 註冊監聽, 當產生了新的state時, 自動呼叫

求和案例使用redux

constant.js

/*
該模組是用於定義actions物件中type型別的常量值
*/ export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

count_action.js

/*
該檔案專門為Count元件生成action物件
*/
import {INCREMENT, DECREMENT} from "./constant"; export const createIncrementAction = data => ({type: INCREMENT, data}) export const createDecrementAction = data => ({type: DECREMENT, data})

count_reducer.js

/*
1.該檔案用於建立一個為Count元件服務的reducer,reducer的本質就是一個函式
2.reducer函式會接收到兩個引數,分別為:之前的狀態(preState),動作物件(action)
*/
import {INCREMENT, DECREMENT} from "./constant"; const initState = 0 //初始化狀態,頁面渲染時會自動呼叫一次
export default function countReducer(preState=initState, action) {
console.log(preState, action)
// 從action物件中獲取type,data
const {type, data} = action
// 根據type決定如何加工資料
switch (type) {
case INCREMENT: // 如果是加
return preState + data;
case DECREMENT: // 如果是減
return preState - data;
default:
return preState
}
}

store.js

/*
1.該檔案用於建立一個為Count元件服務的reducer,reducer的本質就是一個函式
2.reducer函式會接收到兩個引數,分別為:之前的狀態(preState),動作物件(action)
*/
import {INCREMENT, DECREMENT} from "./constant"; const initState = 0 //初始化狀態,頁面渲染時會自動呼叫一次
export default function countReducer(preState=initState, action) {
console.log(preState, action)
// 從action物件中獲取type,data
const {type, data} = action
// 根據type決定如何加工資料
switch (type) {
case INCREMENT: // 如果是加
return preState + data;
case DECREMENT: // 如果是減
return preState - data;
default:
return preState
}
}

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import store from "./redux/store"; ReactDOM.render(<App />, document.getElementById('root')) // 監測redux中狀態的變化,只要變化,就呼叫render
store.subscribe(()=>{
ReactDOM.render(<App />, document.getElementById('root'))
})

Count.jsx

import React, {Component} from 'react';
// 引入store, 用於獲取redux儲存的狀態
import store from "../../redux/store";
// 引入actionCreator, 專門用於建立action物件
import {createDecrementAction, createIncrementAction} from "../../redux/count_action"; class Count extends Component { state = {count: 0} // 第二種方法:第一種在index.js訂閱
// componentDidMount() {
// // 監測redux中狀態的變化,只要變化,就呼叫render
// store.subscribe(()=>{
// this.setState({})
// })
// } increment = () => {
const {value} = this.selectNumber
store.dispatch(createIncrementAction(value*1))
}
decrement = () => {
const {value} = this.selectNumber
store.dispatch(createDecrementAction(value*1)) }
incrementOdd = () => {
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.incrementOdd}>當前求和為奇數加</button>
<button onClick={this.incrementAsync}>非同步加</button>
</div>
);
}
} export default Count;

非同步action版

npm install --save redux-thunk (需安裝使用非同步中介軟體)

store.js中修該

import {createStore, applyMiddleware} from "redux";
// 引入redux-thunk,用於支援非同步action
import thunk from "redux-thunk"; // applyMiddleware使用中介軟體
export default createStore(count_reducer, applyMiddleware(thunk))

count_action.js中修改

import {INCREMENT, DECREMENT} from "./constant";

// 同步action: 就是指action的返回值為Object型別的一般物件
export const createIncrementAction = data => ({type: INCREMENT, data}) export const createDecrementAction = data => ({type: DECREMENT, data}) // 非同步action: 就是指action的返回值為函式,函式自動接收dispatch
// 非同步action中一般都會呼叫同步action,非同步action不是必須要用的
export const createIncrementAsyncAction = (data, time) => {
return (dispatch)=>{
setTimeout(()=>{
dispatch(createIncrementAction(data))
},time)
}
}