理解redux, 并简单实现
redux 作用
Redux is a predictable state container for JavaScript apps.
简单来说, redux 就是一个state容器。 在react 项目中, 我们可以通过redux 来保存共享的状态。
redux 核心API
store
存储数据的容器
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
}
复制代码
- store中常用api
- getState() // 获取store 中state
- dispatch(action) // 触发相应action
- subscribe(listener) // 订阅监听, 即监听dispatch触发
- …
Reducers
to tie state and actions together, we write a function called a reducer. it’s just a function that takes state and action as arguments, and returns the next state of the app.
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }])
default:
return state
}
}
复制代码
reducer 是一个纯函数, 将state 和 action相关联, 接受(state, action) 作为参数, 返回一个新的state。
简单理解: 根据规则改变state
Actions
An action is a plain JavaScript object that describes what happened
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
复制代码
action 是一个 plain object (普通对象)的形式,在使用中, 我们一般定义的格式: { type: '', payload: {}}
action定义了修改state的规则。 只有通过dispatch(触发) action 才能修改store中相应的state
简单使用redux
- store
import { createStore } from 'redux'
import todoReducer from '../reducer'
const store = createStore(todoReducer)
export default store
复制代码
- reducer
const defaultState = [
{
text: "Eat food",
completed: true,
},
{
text: "Exercise",
completed: false,
},
]
const reducer = (state = defaultState, action) => {
const { type, payload } = action || {}
const { text } = payload || {}
switch (type) {
case 'ADD_TODO':
return state.concat([{ text, completed: false }])
default:
return state
}
}
export default reducer
复制代码
- app.js
import React from 'react'
import store from './store'
import './App.css';
class App extends React.Component {
state = {
value: '',
}
componentDidMount() {
store.subscribe(() => {
this.forceUpdate()
})
}
handleConfirm = () => {
const { value } = this.state
if (value) {
const { dispatch } = store
dispatch({ type: 'ADD_TODO', payload: { text: value } })
this.setState({
value: ''
})
}
}
handleChange = (e) => {
this.setState({
value: e.target.value
})
}
render() {
const { value } = this.state
const { getState } = store
const todoList = getState()
return (
<div className="App">
<input value={value} onChange={this.handleChange} />
<button onClick={this.handleConfirm}>确定</button>
{(todoList || []).map((todoItem, index) => {
const { text } = todoItem || {}
return <div key={index}>
内容: { text }
</div>
})}
</div>
);
}
}
export default App;
复制代码
- result
实现redux 核心api
- createStore , 返回一个store, store包含dispatch, getState, subscribe
const createStore = (reducer) => {
let currentState
let currentListeners = []
let nextListeners = currentListeners
const dispatch = (action) => {
currentState = reducer(currentState, action)
currentListeners = nextListeners
currentListeners.forEach(listener => listener())
return action
}
const getState = () => {
return currentState
}
const ensureCanMutateNextListeners = () => {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
const subscribe = (listener) => {
nextListeners.push(listener)
ensureCanMutateNextListeners()
return () => {
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
currentListeners = null
}
}
const store = {
dispatch,
getState,
subscribe,
}
dispatch({type: 'init_____'})
return store
}
export {
createStore
}
复制代码
现在将 上面实例中的redux 引用换成我们自己写的, 效果是一样的。
实例地址
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END