欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解React?Redux使用方法

 更新時(shí)間:2022年09月25日 12:01:16   作者:Rsquo  
這篇文章主要介紹了一文詳解React?Redux使用方法,文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

一、理解JavaScript純函數(shù)

1.1 純函數(shù)的概念

純函數(shù)的維基百科定義:

  • 在程序設(shè)計(jì)中,若一個(gè)函數(shù)符合以下條件,那么這個(gè)函數(shù)被稱為純函數(shù)
  • 此函數(shù)在相同的輸入值時(shí),需產(chǎn)生相同的輸出
  • 函數(shù)的輸出和輸入值以外的其他隱藏信息或狀態(tài)無(wú)關(guān),也和由I/O設(shè)備產(chǎn)生的外部輸出無(wú)關(guān)
  • 該函數(shù)不能有語(yǔ)義上可觀察的函數(shù)副作用,諸如“觸發(fā)事件”,使輸出設(shè)備輸出,或更改輸出值以外物件的內(nèi)容

純函數(shù)概念,總結(jié)如下:

  • 確定的輸入,一定會(huì)產(chǎn)生確定的輸出
  • 函數(shù)在執(zhí)行過(guò)程中,不能產(chǎn)生副作用

案例(數(shù)組的兩個(gè)方法):

  • slice:slice截取數(shù)組時(shí)不會(huì)對(duì)原數(shù)組進(jìn)行任何操作,而是生成一個(gè)新的數(shù)組
  • splice:splice截取數(shù)組, 會(huì)返回一個(gè)新的數(shù)組,也會(huì)對(duì)原數(shù)組進(jìn)行修改

1.2 副作用概念的理解

什么是副作用?

  • 副作用(side effect)表示在執(zhí)行一個(gè)函數(shù)時(shí),除了返回函數(shù)值之外,還對(duì)調(diào)用函數(shù)產(chǎn)生了附加的影響,比如修改了全局變量,修改參數(shù)或者改變外部的存儲(chǔ)

純函數(shù)在執(zhí)行的過(guò)程中就是不能產(chǎn)生這樣的副作用:

  • 副作用往往是產(chǎn)生bug的 “溫床”

1.3 純函數(shù)在函數(shù)式編程的重要性

為什么純函數(shù)在函數(shù)式編程中非常重要呢?

  • 可以安心的編寫和安心的使用
  • 在寫的時(shí)候保證了函數(shù)的純度,只是單純實(shí)現(xiàn)自己的業(yè)務(wù)邏輯即可,不需要關(guān)心傳入的內(nèi)容是如何獲得的或者依賴其他的外部變量是否已經(jīng)發(fā)生了修改
  • 在用的時(shí)候,確定的輸入內(nèi)容不會(huì)被任意篡改,并且自己確定的輸入,一定會(huì)有確定的輸出
  • React中就要求我們無(wú)論是函數(shù)還是class聲明一個(gè)組件,這個(gè)組件都必須像純函數(shù)一樣,保護(hù)它們的props不被修改
  • 在下面的redux中,reducer也被要求是一個(gè)純函數(shù)

二、Redux的核心思想

2.1 為什么需要 Redux

JavaScript開發(fā)的應(yīng)用程序變得越來(lái)越復(fù)雜:

  • JavaScript需要管理的狀態(tài)越來(lái)越多,越來(lái)越復(fù)雜
  • 這些狀態(tài)包括服務(wù)器返回的數(shù)據(jù)、緩存數(shù)據(jù)、用戶操作產(chǎn)生的數(shù)據(jù)等等,也包括一些UI的狀態(tài),比如某些元素是否被選中,是否顯示加載動(dòng)效,當(dāng)前分頁(yè)

管理不斷變化的state是非常困難的:

  • 狀態(tài)之間相互會(huì)存在依賴,一個(gè)狀態(tài)的變化會(huì)引起另一個(gè)狀態(tài)的變化,View頁(yè)面也有可能會(huì)引起狀態(tài)的變化
  • 當(dāng)應(yīng)用程序復(fù)雜時(shí),state在什么時(shí)候,因?yàn)槭裁丛蚨l(fā)生了變化,發(fā)生了怎么樣的變化,會(huì)變得非常難以控制和追蹤

React是在視圖層幫助我們解決了DOM的渲染過(guò)程,但是State依然是留給我們自己來(lái)管理:

  • 無(wú)論是組件定義自己的state,還是組件之間的通信通過(guò)props進(jìn)行傳遞;也包括通過(guò)Context進(jìn)行數(shù)據(jù)之間的共享
  • React主要負(fù)責(zé)幫助我們管理視圖,state如何維護(hù)最終還是我們自己來(lái)決定

  • Redux就是一個(gè)幫助我們管理State的容器:Redux是JavaScript的狀態(tài)容器,提供了可預(yù)測(cè)的狀態(tài)管理
  • Redux除了和React一起使用之外,它也可以和其他界面庫(kù)一起來(lái)使用(比如Vue、小程序),并且它非常?。òㄒ蕾囋趦?nèi),只有2kb)

2.2 Redux的核心概念

2.2.1 store

可以定義一些初始化的數(shù)據(jù),通過(guò) reducer 傳入

2.2.2 action

  • store 中數(shù)據(jù)的變化,必須通過(guò)派發(fā)(dispatch)action來(lái)更新
  • action是一個(gè)普通的JavaScript對(duì)象,用來(lái)描述這次更新的type和content

2.2.3 reducer

將傳入的state和action結(jié)合起來(lái)生成一個(gè)新的state

2.3 Redux的三大原則

2.3.1 單一數(shù)據(jù)源

  • 整個(gè)應(yīng)用程序的state被存儲(chǔ)在一顆object tree中,并且這個(gè)object tree只存儲(chǔ)在一個(gè) store 中
  • Redux并沒(méi)有強(qiáng)制讓我們不能創(chuàng)建多個(gè)Store,但是那樣做并不利于數(shù)據(jù)的維護(hù)
  • 單一的數(shù)據(jù)源可以讓整個(gè)應(yīng)用程序的state變得方便維護(hù)、追蹤、修改

2.3.2 State是只讀的

  • 唯一修改State的方法是觸發(fā)action,不要試圖在其他地方通過(guò)任何的方式來(lái)修改State
  • 這樣就確保了View或網(wǎng)絡(luò)請(qǐng)求都不能直接修改state,它們只能通過(guò)action來(lái)描述自己想要如何修改state
  • 這樣可以保證所有的修改都被集中化處理,并且按照嚴(yán)格的順序來(lái)執(zhí)行,所以不需要擔(dān)心race condition(竟態(tài))的問(wèn)題

2.3.3 使用純函數(shù)來(lái)執(zhí)行修改

  • 通過(guò)reducer將 舊state和 actions聯(lián)系在一起,并且返回一個(gè)新的State
  • 隨著應(yīng)用程序的復(fù)雜度增加,可以將reducer拆分成多個(gè)小的reducers,分別操作不同state tree的一部分
  • 但是所有的reducer都應(yīng)該是純函數(shù),不能產(chǎn)生任何的副作用

2.4 Redux 工作流程

建議看完Redux基本使用后再來(lái)看這幅圖:

三、Redux基本使用

注意:以下 3 部分代碼在 node 環(huán)境下

  • 需要安裝redux:npm install redux

補(bǔ)充:node中對(duì)ES6模塊化的支持

node v13.2.0開始,對(duì)ES6模塊化提供了支持:

node v13.2.0之前,需要進(jìn)行如下操作:

  • 在package.json中添加屬性: "type": "module"
  • 在執(zhí)行命令中添加如下選項(xiàng):node --experimental-modules src/index.js

node v13.2.0之后,只需要進(jìn)行如下操作:

  • 在package.json中添加屬性: "type": "module"
  • 注意:導(dǎo)入文件時(shí),需要跟上.js后綴名

3.1 創(chuàng)建Store的過(guò)程

定義reducer:必須是一個(gè)純函數(shù),不要直接修改state

createStore 傳入 reducer

const { createStore } = require('redux')

// 初始化的數(shù)據(jù)
const initialState = {
  name: '李雷',
  counter: 100
}

// 定義reducer函數(shù):純函數(shù)
// 兩個(gè)參數(shù):
// 參數(shù)一:store中目前保存的state
// 參數(shù)二:本次需要更新的action(dispatch傳入的action)
// 返回值:返回值會(huì)作為store之后存儲(chǔ)的state
function reducer(state = initialState, action) {

  switch (action.type) {
    case 'change_name':
      return { ...state, name: action.name }

    case 'add_numer':
      return { ...state, counter: state.counter + action.num }

    default:
      return state
  }

}
// 創(chuàng)建store
const store = createStore(reducer)

module.exports = store

3.2 dispatch派發(fā)action

  • store 通過(guò) dispatch 來(lái)派發(fā) action
  • 通常會(huì)有 type 屬性,也可以攜帶其他數(shù)據(jù)
const store = require('./store')

console.log(store.getState()) // { name: '李雷', counter: 100 }

// 修改store中的數(shù)據(jù):必須action
const nameAction = { type: 'change_name', name: '韓梅梅' }
store.dispatch(nameAction)
console.log(store.getState()) // { name: '韓梅梅', counter: 100 }

const nameAction2 = { type: 'change_name', name: '夏洛' }
store.dispatch(nameAction2)
console.log(store.getState()) // { name: '夏洛', counter: 100 }

// 修改counter
const counterAction = { type: 'add_numer', num: 10 }
store.dispatch(counterAction)
console.log(store.getState()) // { name: '夏洛', counter: 110 }

3.3 subscribe定位state

  • store.subscribe()傳入一個(gè)函數(shù)能夠監(jiān)聽(tīng)數(shù)據(jù)的變化
  • store.subscribe()會(huì)返回一個(gè)函數(shù),執(zhí)行該函數(shù)取消監(jiān)聽(tīng)
const store = require('./store')

const unSubscribe = store.subscribe(() => {
  console.log('訂閱數(shù)據(jù)的變化:', store.getState())
})

// 修改store中的數(shù)據(jù):必須action
store.dispatch({ type: 'change_name', name: '韓梅梅' })
store.dispatch({ type: 'change_name', name: '夏洛' })

// 取消訂閱
unSubscribe()

// 修改counter
store.dispatch({ type: 'add_numer', num: 10 })

3.4 代碼優(yōu)化

  • 優(yōu)化方向:
    • action的創(chuàng)建放到一個(gè)函數(shù)中
    • 抽取到actionCreators.js文件中
    • 所有的字符串常量放到constants.js文件
    • reducer函數(shù)和初始化值, 放到reducer.js文件
    • index.js中創(chuàng)建store和導(dǎo)出store

示例:

actionCreators.js

const { ADD_NUMBER, CHANGE_NAME } = require("./constants")

const changeNameAction = (name) => ({
  type: CHANGE_NAME,
  name
})
const addNumberAction = (num) => ({
  type: ADD_NUMBER,
  num
})
module.exports = {
  changeNameAction,
  addNumberAction
}
const ADD_NUMBER = "add_number"
const CHANGE_NAME = "change_name"

module.exports = {
  ADD_NUMBER,
  CHANGE_NAME
}
const { CHANGE_NAME, ADD_NUMBER } = require('./constants')

// 初始化的數(shù)據(jù)
const initialState = {
  name: '李雷',
  counter: 100
}

function reducer(state = initialState, action) {
  switch (action.type) {
    case CHANGE_NAME:
      return { ...state, name: action.name }

    case ADD_NUMBER:
      return { ...state, counter: state.counter + action.num }

    default:
      return state
  }
}
module.exports = reducer
const { createStore } = require('redux')
const reducer = require('./reducer')

// 創(chuàng)建store
const store = createStore(reducer)

module.exports = store
const store = require('./store')

const { changeNameAction, addNumberAction } = require('./store/actionCreators')

store.dispatch(changeNameAction('獨(dú)孤月'))
store.dispatch(addNumberAction(100))
console.log(store.getState()) // { name: '獨(dú)孤月', counter: 200 }
  • constants.js
  • reducer.js
  • index.js
  • util.js 中使用

四、Redux 在 React中使用

4.1 先來(lái)一個(gè)案例

有兩個(gè)組件,組件上展示同一個(gè)counter,并且兩者能夠?qū)ounter進(jìn)行操作

  • 創(chuàng)建redux對(duì)應(yīng)的store文件夾

actionCreators.js

import * as actionTypes from './constants'

export const addNumberAction = (num) => ({
  type: actionTypes.ADD_NUMBER,
  num
})

export const subNumberAction = (num) => ({
  type: actionTypes.SUB_NUMBER,
  num
})

constants.js

export const ADD_NUMBER = "add_number"
export const SUB_NUMBER = "sub_number"

reducer.js

import * as actionTypes from './constants'

const initialState = {
  counter: 100
}

function reducer(state = initialState, action) {
  switch (action.type) {
    case actionTypes.ADD_NUMBER:
      return { ...state, counter: state.counter + action.num }

    case actionTypes.SUB_NUMBER:
      return { ...state, counter: state.counter - action.num }

    default:
      return state
  }
}
export default reducer

index.js

import { createStore } from "redux"
import reducer from "./reducer"

const store = createStore(reducer)

export default store

組件中使用:

import React, { PureComponent } from 'react'

// 引入store
import store from '../store'
import { addNumberAction } from '../store/actionCreators'

export default class Home extends PureComponent {

  constructor() {
    super()

    this.state = {
      counter: store.getState().counter
    }
  }

  componentDidMount() {
    store.subscribe(() => {
      const state = store.getState()
      this.setState({ counter: state.counter })
    })
  }

  addNumber(num) {
    store.dispatch(addNumberAction(num))
  }

  render() {
    const { counter } = this.state
    return (
      <div>
        <h2>Home Counter: {counter}</h2>
        <div>
          <button onClick={e => this.addNumber(1)}>+1</button>
          <button onClick={e => this.addNumber(5)}>+5</button>
          <button onClick={e => this.addNumber(8)}>+8</button>
        </div>
      </div>
    )
  }
}
import React, { PureComponent } from 'react'

// 引入store
import store from '../store'
import { subNumberAction } from '../store/actionCreators'

export default class Profile extends PureComponent {
  constructor() {
    super()

    this.state = {
      counter: store.getState().counter
    }
  }
  componentDidMount() {
    store.subscribe(() => {
      const state = store.getState()
      this.setState({ counter: state.counter })
    })
  }
  subNumber(num) {
    store.dispatch(subNumberAction(num))
  }
  render() {
    const { counter } = this.state
    return (
      <div>
        <h2>Profile Counter: {counter}</h2>
        <div>
          <button onClick={e => this.subNumber(1)}>-1</button>
          <button onClick={e => this.subNumber(5)}>-5</button>
          <button onClick={e => this.subNumber(8)}>-8</button>
        </div>
      </div>
    )
  }
}
  • componentDidMount生命周期
  • store.subscribe(() => {}) => this.state => render
  • 修改數(shù)據(jù):store.dispatch(addNumberAction(num))
  • Home.jsx
  • Profile.jsx

4.2 react-redux使用

安裝:npm install react-redux

在使用時(shí)在入口文件中導(dǎo)入 Provider,傳入 store

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

import { Provider } from 'react-redux';
import store from './store'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

在 About 組件中使用:

import React, { PureComponent } from 'react'

import { connect } from 'react-redux'
import { addNumberAction, subNumberAction } from '../store/actionCreators'

export class About extends PureComponent {

  clacNumber(num, isAdd) {
    if(isAdd) {
      this.props.addNumber(num)
    } else {
      this.props.subNumber(num)
    }
  }
  render() {
    const { counter } = this.props
    return (
      <div>
        <h2>About Counter: {counter}</h2>
        <button onClick={e => this.clacNumber(6, true)}>+6</button>
        <button onClick={e => this.clacNumber(9, true)}>+9</button>
        <button onClick={e => this.clacNumber(6, false)}>-6</button>
        <button onClick={e => this.clacNumber(9, false)}>-9</button>
      </div>
    )
  }
}
// connect() 返回值是一個(gè)高階組件
// function mapStateToProps(state) {
//   return {
//     counter: state.counter
//   }
// }

const mapStateToProps = (state) => ({ counter: state.counter })

const mapDispatchToProps = (dispatch) => ({
  addNumber: num => dispatch(addNumberAction(num)),
  subNumber: num => dispatch(subNumberAction(num))
})

export default connect(mapStateToProps, mapDispatchToProps)(About)

connect():

  • 傳入的第一個(gè)函數(shù)是映射當(dāng)前組件所需要的數(shù)據(jù)(store中可能有很多數(shù)據(jù),比如books、counter,而此處只需要counter)
  • 傳入的第二個(gè)函數(shù)是映射 dispatch 到 props
  • 返回一個(gè)高階組件

4.3 組件中的異步操作

4.3.1 類組件生命周期中請(qǐng)求數(shù)據(jù)

  • 在class組件的componentDidMount中發(fā)送請(qǐng)求

通過(guò)發(fā)起action將請(qǐng)求的數(shù)據(jù)保存到store中

action方法:

export const changeBannersAction = (banners) => ({
  type: actionTypes.CHANGE_BANNERS,
  banners
})

export const changeRecommendsAction = (recommends) => ({
  type: actionTypes.CHANGE_RECOMMENDS,
  recommends
})
import * as actionTypes from './constants'

const initialState = {
  counter: 100,

  banners: [],
  recommends: []
}

function reducer(state = initialState, action) {
  switch (action.type) {
    case actionTypes.CHANGE_BANNERS:
      return { ...state, banners: action.banners }

    case actionTypes.CHANGE_RECOMMENDS:
      return { ...state, recommends: action.recommends }

    default:
      return state
  }
}

export default reducer
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import axios from 'axios'
import { changeBannersAction, changeRecommendsAction } from '../store/actionCreators'

export class Category extends PureComponent {

  componentDidMount() {
    // 發(fā)送請(qǐng)求
    axios.get('http://123.207.32.32:8000/home/multidata').then(res => {
      const banners = res.data.data.banner.list
      const recommends = res.data.data.recommend.list
      this.props.changeBanners(banners)
      this.props.changeRecommends(recommends)
    })
  }

  render() {
    return (
      <div>
        <h2>Category Page</h2>
      </div>
    )
  }
}

const mapDispatchToProps = (dispacth) => ({
  changeBanners: banners => dispacth(changeBannersAction(banners)),
  changeRecommends: recommends => dispacth(changeRecommendsAction(recommends))
})

export default connect(null, mapDispatchToProps)(Category)
  • reducer
  • category組件

4.3.2 使用中間件

上面的代碼有一個(gè)缺陷:

  • 我們必須將網(wǎng)絡(luò)請(qǐng)求的異步代碼放到組件的生命周期中來(lái)完成
  • 事實(shí)上,網(wǎng)絡(luò)請(qǐng)求到的數(shù)據(jù)也屬于狀態(tài)管理的一部分,更好的一種方式應(yīng)該是將其也交給redux來(lái)管理

如何將異步請(qǐng)求交給 Redux?

  • 一個(gè)普通的action,返回的是一個(gè)對(duì)象 { type: CHANGE_COUNTER, num: 10 }
  • 對(duì)象中是無(wú)法直接拿到服務(wù)器請(qǐng)求到的異步數(shù)據(jù)的,但是如果返回一個(gè)函數(shù)呢?
  • 返回一個(gè)函數(shù),然后在組件中發(fā)起 Action 的時(shí)候,執(zhí)行這個(gè)函數(shù)是不是就能夠拿到數(shù)據(jù)了呢?。?!
  • !?。?/strong> 普通的 action 不能返回函數(shù),可以借助中間件來(lái)增強(qiáng)一下,讓他支持返回一個(gè)函數(shù),官網(wǎng)推薦的中間件:redux-thunk
  • 中間件的目的:是在dispatch的action和最終達(dá)到的reducer之間,擴(kuò)展一些自己的代碼

redux-thunk 做了什么呢

  • dispatch(action函數(shù))中的action可以是一個(gè)函數(shù);
  • 該函數(shù)會(huì)被調(diào)用,并且會(huì)傳給這個(gè)函數(shù)一個(gè)dispatch函數(shù)和getState函數(shù);
    • dispatch函數(shù)用于之后再次派發(fā)action
    • getState函數(shù)考慮到我們之后的一些操作需要依賴原來(lái)的狀態(tài),用于獲取之前的一些狀態(tài)

代碼演示:

import { createStore, applyMiddleware } from "redux"
import thunk from "redux-thunk"
import reducer from "./reducer"

// 正常情況下 store.dispatch(object)
// 想要派發(fā)函數(shù) store.dispatch(function)

// applyMiddleware 可以傳入多個(gè)中間件,","隔開
const store = createStore(reducer, applyMiddleware(thunk))

export default store
import * as actionTypes from './constants'
import axios from 'axios'

export const changeBannersAction = (banners) => ({
  type: actionTypes.CHANGE_BANNERS,
  banners
})

export const changeRecommendsAction = (recommends) => ({
  type: actionTypes.CHANGE_RECOMMENDS,
  recommends
})

export const fetchHomeMultidataAction = () => {
  // 如果是一個(gè)普通的action,需要返回action對(duì)象
  // 問(wèn)題: 對(duì)象中不能直接拿到從服務(wù)器請(qǐng)求的異步數(shù)據(jù)

  // redux 不允許返回一個(gè)函數(shù),需要中間件
  return (dispatch, getState) => {
    // console.log(getState().counter) // 100
    // 進(jìn)行異步操作: 網(wǎng)絡(luò)請(qǐng)求
    axios.get('http://123.207.32.32:8000/home/multidata').then(res => {
      const banners = res.data.data.banner.list
      const recommends = res.data.data.recommend.list
      // dispatch({type: actionTypes.CHANGE_BANNERS, banners})
      // dispatch({type: actionTypes.CHANGE_RECOMMENDS, recommends})
      dispatch(changeBannersAction(banners))
      dispatch(changeRecommendsAction(recommends))
    })
  }

}
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { fetchHomeMultidataAction } from '../store/actionCreators'

export class Category extends PureComponent {

  componentDidMount() {
    this.props.fetchHomeMultidata()
  }

  render() {
    return (
      <div>
        <h2>Category Page</h2>
      </div>
    )
  }
}

const mapStateToProps = state => ({
  counter: state.counter
})

const mapDispatchToProps = (dispacth) => ({
  fetchHomeMultidata: () => dispacth(fetchHomeMultidataAction())
})

export default connect(mapStateToProps, mapDispatchToProps)(Category)
  • store(index.js) 中引入thunk
  • actionCreators.js
  • 組件中使用

4.4 redux-devtools

redux可以方便的對(duì)狀態(tài)進(jìn)行跟蹤和調(diào)試

  • redux官網(wǎng)提供了redux-devtools的工具
  • 利用這個(gè)工具,可以知道每次狀態(tài)是如何被修改的,修改前后的狀態(tài)變化等等

安裝該工具需要兩步:

  • 在對(duì)應(yīng)的瀏覽器中安裝相關(guān)的插件(比如Chrome瀏覽器擴(kuò)展商店中搜索Redux DevTools即可)
  • 在redux中繼承devtools的中間件

默認(rèn)該工具是未開啟的,開發(fā)環(huán)境開啟需要進(jìn)行配置,生產(chǎn)環(huán)境千萬(wàn)千萬(wàn)不要打開哦!??!

import { createStore, applyMiddleware, compose } from "redux"
import thunk from "redux-thunk"
import reducer from "./reducer"

// redux-devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace: true}) || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)))

export default store
復(fù)制代碼

4.5 模塊拆分

正常情況下,我們的 store 中應(yīng)該是有不同狀態(tài)的數(shù)據(jù),比如:購(gòu)物車、用戶信息等等, 如果將所有的狀態(tài)都放到一個(gè)reducer中進(jìn)行管理,隨著項(xiàng)目的日趨龐大,必然會(huì)造成代碼臃腫、難以維護(hù)。因此,我們可以對(duì)reducer進(jìn)行拆分

以上面提到的案例為例,抽取一個(gè) counter 的reducer和一個(gè) home 的reducer,再將其合并起來(lái)

分不同的模塊,每個(gè)模塊都包含自己的核心:

>reducer:接收action對(duì)象,返回最新的state

  • constants:定義常量數(shù)據(jù)
  • actioncreators:定義創(chuàng)建action對(duì)象的函數(shù)
  • index:導(dǎo)出reducer

在 index.js 中導(dǎo)入每一個(gè)模塊的內(nèi)容,通過(guò)combineReducers合并之后放入createStore

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

import counterReducer from './counter'
import homeReducer from './home'
import userReducer from './user'

// 將reducer合并到一起
const reducer = combineReducers({
  counter: counterReducer,
  home: homeReducer,
  user: userReducer
})

// redux-devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace: true}) || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)))

export default store

combineReducers 如何實(shí)現(xiàn)合并呢?

  • 事實(shí)上,它是將我們傳入的reducers合并到一個(gè)對(duì)象中,最終返回一個(gè)combination的函數(shù)(相當(dāng)于我們的reducer函數(shù)了)
  • 在執(zhí)行combination函數(shù)的過(guò)程中,它會(huì)通過(guò)判斷前后返回的數(shù)據(jù)是否相同來(lái)決定返回之前的state還是新的state
  • 新的state會(huì)觸發(fā)訂閱者發(fā)生對(duì)應(yīng)的刷新,而舊的state可以有效的阻止訂閱者發(fā)生刷新
// combineReducers 原理
function reducer(state = {}, action) {

  // 返回一個(gè)對(duì)象,store中的state
  return {
    counter: counterReducer(state.counter, action),
    home: homeReducer(state.home, action),
    user: userReducer(state.user, action)
  }
}

到此這篇關(guān)于一文詳解React Redux使用方法的文章就介紹到這了,更多相關(guān)React Redux使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于React實(shí)現(xiàn)無(wú)限滾動(dòng)表格

    基于React實(shí)現(xiàn)無(wú)限滾動(dòng)表格

    以文本為例,為了實(shí)現(xiàn)無(wú)限循環(huán)的視覺(jué)效果,我們需要準(zhǔn)備兩段相同的文本,并讓第二段文本的頭部銜接在第一段文本的尾部,同時(shí),為兩段文本設(shè)置相同的滾動(dòng)動(dòng)畫,本文給大家介紹了基于React實(shí)現(xiàn)無(wú)限滾動(dòng)表格,需要的朋友可以參考下
    2023-11-11
  • 使用React+SpringBoot開發(fā)一個(gè)協(xié)同編輯的表格文檔實(shí)現(xiàn)步驟

    使用React+SpringBoot開發(fā)一個(gè)協(xié)同編輯的表格文檔實(shí)現(xiàn)步驟

    隨著云計(jì)算和團(tuán)隊(duì)協(xié)作的興起,協(xié)同編輯成為了許多企業(yè)和組織中必不可少的需求,本文小編就將為大家介紹如何使用React+SpringBoot簡(jiǎn)單的開發(fā)一個(gè)協(xié)同編輯的表格文檔,感興趣的朋友一起看看吧
    2023-11-11
  • React Native:react-native-code-push報(bào)錯(cuò)的解決

    React Native:react-native-code-push報(bào)錯(cuò)的解決

    這篇文章主要介紹了React Native:react-native-code-push報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • React?Hydrate原理源碼解析

    React?Hydrate原理源碼解析

    這篇文章主要為大家介紹了React?Hydrate原理源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 深入理解react-router@4.0 使用和源碼解析

    深入理解react-router@4.0 使用和源碼解析

    這篇文章主要介紹了深入理解react-router@4.0 使用和源碼解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • React中使用antd組件的方法

    React中使用antd組件的方法

    antd?是基于?Ant?Design?設(shè)計(jì)體系的?React?UI?組件庫(kù),主要用于研發(fā)企業(yè)級(jí)中后臺(tái)產(chǎn)品,這篇文章主要介紹了React中使用antd組件,需要的朋友可以參考下
    2022-09-09
  • 再次談?wù)揜eact.js實(shí)現(xiàn)原生js拖拽效果引起的一系列問(wèn)題

    再次談?wù)揜eact.js實(shí)現(xiàn)原生js拖拽效果引起的一系列問(wèn)題

    React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來(lái)架設(shè) Instagram 的網(wǎng)站.本文給大家介紹React.js實(shí)現(xiàn)原生js拖拽效果,需要的朋友一起學(xué)習(xí)吧
    2016-04-04
  • React為 Vue 引入容器組件和展示組件的教程詳解

    React為 Vue 引入容器組件和展示組件的教程詳解

    這篇文章主要介紹了React為 Vue 引入容器組件和展示組件的教程詳解,文中很詳細(xì)的給大家介紹了使用容器組件的原因,需要的朋友可以參考下
    2018-05-05
  • Hello?React的組件化方式之React入門小案例演示

    Hello?React的組件化方式之React入門小案例演示

    這篇文章主要介紹了Hello?React的組件化方式-React入門小案例,本文通過(guò)Hello?React的案例,?來(lái)體驗(yàn)一下React開發(fā)模式,?以及jsx的語(yǔ)法,需要的朋友可以參考下
    2022-10-10
  • react render的原理及觸發(fā)時(shí)機(jī)說(shuō)明

    react render的原理及觸發(fā)時(shí)機(jī)說(shuō)明

    這篇文章主要介紹了react render的原理及觸發(fā)時(shí)機(jī)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論