redux
介绍:
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 (如果你需要一个 WordPress 框架,请查看 Redux Framework。)
可以让你构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。不仅于此,它还提供 超爽的开发体验,比如有一个时间旅行调试器可以编辑后实时预览。
Redux 除了和 React 一起用外,还支持其它界面库。 它体小精悍(只有2kB,包括依赖)。
阮一峰 redux教程: www.ruanyifeng.com/blog/2016/0…
导出使用
// import { createStore } from 'redux'
import { createStore } from './util/store.js'
import { applyMiddleware } from 'redux'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
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))
// applyMiddleware(thunk, logger) 支持传入函数进行操作、支持日志
export default store
页面使用
import React, { Component } from 'react'
import store from './store'
export default class ReduxPage extends Component {
componentDidMount() {
store.subscribe(() => {
this.forceUpdate()
})
}
add = () => {
store.dispatch({
type: 'ADD'
})
}
minus = () => {
store.dispatch({
type: 'MINUS'
})
}
asyAdd = () => {
// 支持传入一个函数 // 可以获得 dispatch, getState
store.dispatch((dispatch, getState) => {
setTimeout(() => {
console.log('now ', getState()) //sy-log
dispatch({ type: 'ADD' })
}, 1000)
})
}
render() {
console.log('store', store) //sy-log
return (
<div>
{' '}
<h3>ReduxPage</h3>
<p>{store.getState()}</p>
<button onClick={this.add}>add</button>
<button onClick={this.minus}>minus</button> {/* <button onClick={this.minus}>minus</button>{' '} */}
<button onClick={this.asyAdd}>asyAdd</button>{' '}
</div>
)
}
}
原理 store.js
export default function createStore(reducer, enhancer) {
if (enhancer) { // 插件
return enhancer(createStore)(reducer) // 下章讲解
}
let currentState // 存储初始值
let currentListeners = []
function getState() {
return currentState
}
function dispatch(action) {
currentState = reducer(currentState, action)
currentListeners.forEach((listener) => listener())
return action
}
function subscribe(listener) {
currentListeners.push(listener)
return () => {
const index = currentListeners.indexOf(listener)
currentListeners.splice(index, 1)
}
}
dispatch({
type: 'init'
})
return {
getState,
dispatch,
subscribe
}
}