理解redux, 并简单实现

理解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

  1. store
import { createStore } from 'redux'
import todoReducer from '../reducer'

const store = createStore(todoReducer)

export default store
复制代码
  1. 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

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
喜欢就支持一下吧
点赞0 分享