一. 为什么要用redux?
- 来一张图看看😂
二. redux是什么?
- 再来一张图看看😂
三. redux三大原则
- 唯一数据源
- 整个应用的state都被存储到一个状态树里面,并且这个状态树,只存在于唯一的store中。
- 保持只读状态
- state是只读的,唯一改变state的方法就是触发action,action是一个用于描述以发生时间的普通对象。
- 数据改变只能通过纯函数来执行
- 使用纯函数来执行修改,为了描述action如何改变state的,你需要编写reducers。
四. redux的使用
- 先来了解几个核心概念
- store:存储数据的仓库
- reducer:初始化state并定义state修改规则
- dispatch:提交action(reducer定义好的),修改store数据的一个方法
- getState:获取状态值
- subscribe:订阅state状态更新
- 上代码
- 创建store,src/store.js
import {createStore} from 'redux' const counterReducer = (state = 0, action) => { switch (action.type) { case 'add': return state + 1 case 'minus': return state - 1 default: return state } } const store = createStore(counterReducer) export default store- 创建page,src/view/counter.js
import React, { Component } from "react"; import store from "../store"; export default class counter extends Component { componentDidMount() { // 订阅状态变更,强制刷新。 // 如果不这么做,数据更新之后,页面不会刷新,这点和vuex不一样,因为vuex有响应式,但是它没有。 store.subscribe(() => this.forceUpdate()); } render() { return ( <div> <!-- 获取state的值 --> <p>{store.getState()}</p> <div> <button onClick={() => store.dispatch({ type: "add" })}>+</button> <button onClick={() => store.dispatch({ type: "minus" })}>-</button> </div> </div> ); } }- 订阅状态变更,index.js
import store from './store' const render = () => { ReactDom.render( <App/>, document.querySelector('#root') ) } render() store.subscribe(render)
五. 说了应用,咱们再聊聊实现
- 咱们这次核心要实现的是四个模块:state,getState,dispatch,subscribe
- 代码如下
export function createStore (reducer, enhancer) { if (enhancer) { // 除了创建store之外,再做一些其他事情 return enhancer(createStore)(reducer) } // 保存状态 let currentState = undefined; let currentListeners = []; // 回调函数的数组 function getState () { return currentState } // 订阅模式 function subscribe (listener) { currentListeners.push(listener) } // 更新状态 function dispatch (action) { // 修改 currentState = reducer(currentState, action) // 变更通知 currentListeners.forEach(listener => listener()) return action } return { getState, subscribe, dispatch} }
六. 总结
- 单纯的使用redux,每次数据更新,都需要强制刷新有些麻烦,react为我们提供的react-redux可以帮我们解决这个问题,下次可以重点聊聊。