image.png

这就是 redux的基本流程.
store中维护着一个状态 state, 组件组订阅这个状态.
如果组件需要更新这个状态, 就定义一个 action, 通过 store.dispatch方法, 告知 state的维护者 reducer, 我这个 action需要改变 state.
然后 reducer就收到这个 action, 去执行操作.
因为这个组件是订阅了 storestate的, 所以一旦 state发生改变, 组件内部的 state就会立即更新.

创建一个管理者, 导出state, 放在store里面

let initialState = {
    title: '',
    list: []
}

export default (state = initialState, action) => {
   return state;
}

创建一个store

import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store

window.... 的作用是能使用redux Dev Tools查看状态变化.
还是以最经典的TodoList为例. 需要对待办事项进行添加删除

import React from 'react'
import store from '../store/index'     // 导入 store

export default class TodoList extends React.Component{
    state = store.getState()    // 初始化 state, 直接获取 store 里面的 state
    handleChange = (e) => {
        // 定义一个 action 给定一个 TYPE 把 value 带上
        const action = {
            type: 'CHANGE_TITLE',
            value: e.target.value
        }
        store.dispatch(action)  // 通过 dispatch 处理这个 action 
    }
    componentDidMount() {  // 当组件挂载完成的时候, 就订阅状态
        store.subscribe(this.handleStateChange)
    }
    handleStateChange = () => {
        this.setState(store.getState())
    }
    handleAddItem = () => {
        const action = {
            type: 'ADD_TODO_ITEM',
            value: this.state.title
        }
        store.dispatch(action)
    }
    deleteItem = (index) => {
        const action = {
            type: 'DELETE_TODO_ITEM',
            index: index
        }
        store.dispatch(action)
    }
    render() {
        return (
            <>
                <div>
                    <input type="text" value={ this.state.title } onChange={ this.handleChange }/>
                    <button onClick={this.handleAddItem}> Add </button>
                </div>
                <ul>
                    {
                        this.state.list.map((item, index) => {
                            return (
                                <li key={item+index}>
                                    <span>{item}</span>
                                    <button onClick={ () => this.deleteItem(index) }> delete </button>
                                </li>
                            )
                        })
                    }
                </ul>
            </>
        );
    }
}

然后在 reducer 中, 对不同类型的 action 进行针对性的处理

let initState = {
    title: '',
    list: []
}


export default (state = initState, action) => {
    const newState = JSON.parse(JSON.stringify(state))
    switch (action.type) {
        case 'CHANGE_TITLE':
            newState.title = action.value
            return newState
        case 'ADD_TODO_ITEM':
            newState.list.push(action.value)
            newState.title = ''
            return newState
        case 'DELETE_TODO_ITEM':
            newState.list.splice(action.index, 1)
            return newState
        default:
            return state;
    }

}