天天看點

redux 基本使用

文章目錄

    • redux 簡介
    • redux 三大原則
      • 單一資料源
      • State 是隻讀的
      • 使用純函數來執行修改
    • redux 核心理念
      • 安裝依賴
      • store
      • action
      • reducer
      • constant.js
      • state.js
      • 頁面使用

redux 簡介

redux 是一個幫助我們管理State的容器:redux是JavaScript的狀态容器,提供了可預測的狀态管理

redux 不是隻能用于 react 中的,它還可以用在 vue 等其它架構中

redux 的主要作用就是:集中式管理(讀/寫)react 應用中多個元件共享狀态

redux 三大原則

單一資料源

  • 整個應用程式的state被存儲在一顆object tree中,并且這個object tree隻存儲在一個 store 中
  • 單一的資料源可以讓整個應用程式的state變得友善維護、追蹤、修改

State 是隻讀的

  • 唯一修改State的方法一定是觸發action(一個用于描述已發生事件的普通對象),不要試圖在其他地方通過任何的方式來修改State
  • 這樣就確定了View或網絡請求都不能直接修改state,它們隻能通過action來描述自己想要如何修改state
  • 這樣可以保證所有的修改都被集中化處理,并且按照嚴格的順序來執行,是以不需要擔心race condition(竟态)的問題

使用純函數來執行修改

  • 通過reducer将 舊state和 actions聯系在一起,并且傳回一個新的State
  • 随着應用程式的複雜度增加,我們可以将reducer拆分成多個小的reducers,分别操作不同state tree的一部分
  • 但是所有的reducer都應該是純函數,不能産生任何的副作用

redux 核心理念

dispatch(派發器觸發actions中的對應方法)=>actions(具體去觸發對應的reducer的方法)=>reducer(j具體的修改state中的資料的方法)=>subscribe(訂閱者,state中的資料變化,就會觸發)=>unsubscribe(取消訂閱)

安裝依賴

yarn add redux redux-thunk
           

store

import {createStore,applyMiddleware} from "redux"
import thunk from "redux-thunk"

import reduce from "./reduce"

const store =createStore(reduce,applyMiddleware(thunk))

export default store
           

如果有多個reducer需要合并

import {createStore,applyMiddleware,combineReducers} from "redux"
import thunk from "redux-thunk"

import reduce from "./reduce"
// 如果有多個reducer 需要連接配接後使用,這樣,在使用 state中的資料,需要 .count
const allReducers =combineReducers({
    count:reduce
})

const store =createStore(allReducers,applyMiddleware(thunk))

export default store
           

actions不受影響

useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setCount(store.getState().count.count)
    })

    return () => {
      unsubscribe()
    }
  }, [])
           

action

派發事件中心(不能修改資料)

import {
    INCREMENT,
    DECREMENT
} from "./constant"

export const incrementAction= data =>({
    type:INCREMENT,
    data
})

export const decrementAction= data =>({
    type:DECREMENT,
    data
})

export const decrementActionAsync= data =>{
    return dispatch=>{
        setTimeout(()=>{
            dispatch(incrementAction(data))
        },1000)
    }
}
           

reducer

真正修改資料的地方

import initState from "./state"
import {
    INCREMENT,
    DECREMENT
} from "./constant"

export default function createRender(state = initState, action) {
    console.log(state);
    switch (action.type) {
        case INCREMENT:
            return { ...state, count: state.count + action.data }
        case DECREMENT:
            return { ...state, count: state.count - action.data }
        default:
            return state
    }
}
           

constant.js

const INCREMENT="increment"
 const DECREMENT="decrement"

export {
    INCREMENT,
    DECREMENT
}
           

state.js

export default {
    count : 0
}
           

頁面使用

import React, { memo, useEffect, useState } from 'react'
import store from "./store"
import { incrementAction, decrementAction, decrementActionAsync } from "./store/actions"

function App() {
  const [count, setCount] = useState(0)
  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setCount(store.getState().count)
    })

    return () => {
      unsubscribe()
    }
  }, [])

  return (
    <div>
      <h2>
        {count}
      </h2>
      <button onClick={() => {
        store.dispatch(incrementAction(1))
      }}>
        +1
      </button>
      <hr />
      <button onClick={() => {
        store.dispatch(decrementAction(5))
      }}>
        -5
      </button>
      <hr />
      <button onClick={() => {
        store.dispatch(decrementActionAsync(5))
      }}>
        異步+5
      </button>
    </div>
  )
}

export default memo(App)