redux例子
Redux:JavaScript状态管理容易,保证行为一致性及易于测试可追踪。
Redux流程:
1. createStore 创建 store;
2. reducer 初始化、修改状态函数;reducer 是一个纯函数,接收旧的 state 和 action,返回新的 state;
3. getState 获取状态值;
4. dispatch 提交更新;
5. subscribe 变更订阅;
redux同步例子
// App.js import React from "react"; import ReduxPage from "./pages/ReduxPage.js"; function App() { return ( <div className="App"> <ReduxPage /> </div> ); } export default App; // store/index.js import { createStore } from "redux"; // 定义修改规则 function countReducer(state = 0, action) { switch (action.type) { case "ADD": return state + 1; case "MINUS": return state - 1; default: return state; } } const store = createStore(countReducer); export default store; // pages/ReduxPage.js import React, { Component } from "react"; import store from "../store/index"; export default class ReduxPage extends Component { componentDidMount() { // 订阅 store.subscribe(() => { this.forceUpdate(); }); } add = () => { // 派发 store.dispatch({ type: "ADD" }); }; minus = () => { store.dispatch({ type: "MINUS" }); }; render() { // 获取数据 return ( <div> <h3>ReduxPage</h3> <p>{store.getState()}</p> <button onClick={this.add}>add</button> <button onClick={this.minus}>minus</button> </div> ); } }
redux的dispatch只支持传入对象,若想实现更复杂的内容,如传入函数,实现异步操作,请求接口获取数据等,可以选择借助中间件增强其功能,如redux-thunk
// store/index.js import { createStore, applyMiddleware } from "redux"; import thunk from "redux-thunk"; import logger from "redux-logger"; // 定义修改规则 function countReducer(state = 0, action) { switch (action.type) { case "ADD": return state + 1; case "MINUS": return state - 1; default: return state; } } const store = createStore(countReducer, applyMiddleware(thunk, logger)); export default store; // ReduxPage.js import React, { Component } from "react"; import store from "../store/index"; export default class ReduxPage extends Component { componentDidMount() { store.subscribe(() => { this.forceUpdate(); }); } add = () => { store.dispatch({ type: "ADD" }); }; minus = () => { store.dispatch({ type: "MINUS" }); }; asyAdd = () => { store.dispatch((dispatch) => { console.log("123"); setTimeout(() => { dispatch({ type: "ADD" }); }, 1000); }); }; render() { return ( <div> <h3>ReduxPage</h3> <p>{store.getState()}</p> <button onClick={this.add}>add</button> <button onClick={this.minus}>minus</button> <button onClick={this.asyAdd}>asyAdd</button> </div> ); } }
异步:利用中间件redux-thunk
// store/index.js
import { createStore, applyMiddleware } from "redux"; import thunk from "redux-thunk"; import logger from "redux-logger"; export const counterReducer = (state = 0, { type, payload = 1 }) => { switch (type) { case "ADD": return state + payload; case "MINUS": return state - payload; default: return state; } }; const store = createStore(counterReducer, applyMiddleware(thunk, logger)); export default store;
// ReduxpageTest.js
import React, { Component } from "react"; import store from "../store"; class ReduxPage extends Component { componentDidMount() { // state发生变化时订阅 this.unsubscibe = store.subscribe(() => { this.forceUpdate(); }); } add = () => { store.dispatch({ type: "ADD", payload: 11 }); }; asyncAdd = () => { store.dispatch((dispatch, getState) => { setTimeout(() => { // store.dispatch({ type: "ADD" }); dispatch({ type: "ADD" }); }, 1000); }); }; componentWillUnmount() { if (this.unsubscibe) { this.unsubscibe(); } } render() { return ( <div> <h1>ReduxPage</h1> <p>count:{store.getState()}</p> <button onClick={this.add}>+</button> <button onClick={this.asyncAdd}>asyncAdd+</button> </div> ); } } export default ReduxPage;
combineReducers:
// store/index.js
import { createStore, applyMiddleware, combineReducers } from "redux"; import thunk from "redux-thunk"; import logger from "redux-logger"; export const counterReducer = (state = 0, { type, payload = 1 }) => { switch (type) { case "ADD": return state + payload; case "MINUS": return state - payload; default: return state; } }; const store = createStore( combineReducers({ count: counterReducer }), applyMiddleware(thunk, logger) ); export default store;
// 状态获取
<p>count:{store.getState().count}</p>
ps:感谢&参考 各路大神
宝剑锋从磨砺出,梅花香自苦寒来。