最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React狀態(tài)管理Redux的使用介紹詳解

 更新時(shí)間:2022年09月28日 14:53:06   作者:月光曬了很涼快  
redux是redux官方react綁定庫(kù),能夠使react組件從redux store中讀取數(shù)據(jù),并且向store分發(fā)actions以此來(lái)更新數(shù)據(jù),這篇文章主要介紹了react-redux的設(shè)置,需要的朋友可以參考下

1. 簡(jiǎn)介

Redux 是 JavaScript 應(yīng)用的狀態(tài)容器(對(duì)象),提供可預(yù)測(cè)的狀態(tài)管理??梢宰屇汩_(kāi)發(fā)出行為穩(wěn)定可預(yù)測(cè)的應(yīng)用,運(yùn)行于不同的環(huán)境(客戶端、服務(wù)器、原生應(yīng)用),并且易于測(cè)試。Redux 除了和 React 一起用外,還支持其它界面庫(kù)。

解決的問(wèn)題:多層級(jí)組件間通信問(wèn)題。

2. 核心概念

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

整個(gè)redux中的數(shù)據(jù)都是集中管理,存儲(chǔ)于同一個(gè)數(shù)據(jù)源中,數(shù)據(jù)源中的數(shù)據(jù)為單向數(shù)據(jù)流,不可直接修改。

純函數(shù) (reducer) 統(tǒng)一對(duì) state 數(shù)據(jù)修改

redux 定義了一個(gè) reducer 函數(shù)來(lái)完成 state 數(shù)據(jù)的修改,reducer 會(huì)接收先前的 state 和 action,并返回新的 state。

  • 函數(shù)執(zhí)行結(jié)果是可預(yù)期的(多次調(diào)用結(jié)果相同)
  • 函數(shù)執(zhí)行不會(huì)觸發(fā)副作用
  • 函數(shù)中的變量,沒(méi)有使用外部的

3. redux工作流

①、store通過(guò) reducer 創(chuàng)建了初始狀態(tài)

②、component 通過(guò) store.getState() 獲取到了 store 中保存的 state 掛載在了自己的狀態(tài)上

③、用戶產(chǎn)生了操作,調(diào)用了 actions 的方法

④、actions 的方法被調(diào)用,創(chuàng)建了帶有標(biāo)示性信息的 action(描述對(duì)象)

⑤、actions 將 action 通過(guò)調(diào)用 store.dispatch 方法發(fā)送到了 reducer 中

⑥、reducer 接收到 action 并根據(jù)標(biāo)識(shí)信息判斷之后返回了新的 state

⑦、store 的 state 被 reducer 更改為新 state 的時(shí)候,store.subscribe 方法里的回調(diào)函數(shù)會(huì)執(zhí)行,此時(shí)就可以通知 component 去重新獲取 state

4. 模擬redux工作流程

redux.js:

// 自定義的redux狀態(tài)管理
// 用 createStore 方法接收 reducer 純函數(shù)
export const createStore = reducer => {
    // 接收新的帶有單一數(shù)據(jù)源的對(duì)象
    let state = undefined
    // 訂閱隊(duì)列
    let tasks = []
    // 3.store.dispatch({type,payload})
    const dispath = action => {
        // 將 action 交給 reducer ,返回一個(gè)新的數(shù)據(jù)源
        state = reducer(state, action)
        // 數(shù)據(jù)源發(fā)生變化時(shí),讓訂閱隊(duì)列中的每一個(gè)回調(diào)函數(shù)執(zhí)行
        tasks.forEach(cb => cb())
    }
    const subscribe = cb => {
        // 把回調(diào)函數(shù)放入訂閱隊(duì)列中
        tasks.push(cb)
        // 取消訂閱時(shí),刪除訂閱隊(duì)列中的回調(diào)函數(shù)
        return () => tasks.splice(tasks.indexOf(cb), 1)
    }
    // 返回?cái)?shù)據(jù)源
    const getState = () => state
    // 2.初始化,防止組件第一次調(diào)用 getState 得到的是 undefined
    dispath({ type: '@@init@@' })
    // 返回 redux 工作流中需要的三個(gè)函數(shù)
    return {
        dispath,
        subscribe,
        getState
    }
}

index.js:

// 導(dǎo)入倉(cāng)庫(kù)
import { createStore } from './redux'
// 5.設(shè)置一個(gè)初始值
const initState = {
    num: 100
}
// 4.創(chuàng)建 reducer 純函數(shù)
const reducer = (state = initState, action) => {
    // 完成組件中加的操作
    if (action.type === 'add') return { ...state, num: state.num + action.payload }
    return state;
}
const store = createStore(reducer)
export default store

App.jsx:

import React, { Component } from 'react'
// 組件中導(dǎo)入倉(cāng)庫(kù)
import store from './store'
class App extends Component {
  componentDidMount() {
    // 訂閱 redux 的頻道,只要頻道發(fā)生更改,就會(huì)觸發(fā)視圖更新
    // 并且讓 unsubscribe 接收到 redux 中取消訂閱的函數(shù)
    this.unsubscribe = store.subscribe(() => this.forceUpdate())
  }
  componentWillUnmount() {
    // 取消訂閱,組件卸載時(shí)執(zhí)行
    this.unsubscribe()
  }
  render() {
    return (
      <div>
        {/* 1.組件通過(guò) getState 得到數(shù)據(jù) */}
        <h3>{store.getState().num}</h3>
        <hr />
        <button
          onClick={() => {
            // 動(dòng)作:添加;數(shù)據(jù):每次加2
            store.dispath({ type: 'add', payload: 2 })
          }}
        >
          ++++
        </button>
      </div>
    )
  }
}
export default App

5. 使用redux

安裝 redux:

redux 沒(méi)有內(nèi)嵌在 react 框架中,使用時(shí)需要手動(dòng)去安裝:yarn add redux

安裝 redux-devtools:

安裝第3方模塊,讓調(diào)試工具顯示 state:

# yarn add -D @redux-devtools/extension
import { composeWithDevTools } from '@redux-devtools/extension'
const store = createStore(
  reducer,
  composeWithDevTools()
);

把上述案例,用真實(shí)的 redux 實(shí)現(xiàn)一下:

index.js:

// 1.導(dǎo)入redux中的createStore創(chuàng)建倉(cāng)庫(kù)數(shù)據(jù)的方法
import { createStore } from 'redux'
// 配合瀏覽器安裝的插件來(lái)進(jìn)行redux調(diào)試所用  
// 開(kāi)發(fā)時(shí)有用,生產(chǎn)要關(guān)閉
import { composeWithDevTools } from '@redux-devtools/extension'
// 2.初始state數(shù)據(jù)
const initState = {
  num: 100
}
// 3.定義一個(gè)純函數(shù)reducer,專門用來(lái)操作state中的數(shù)據(jù),要返回一個(gè)新的state
const reducer = (state = initState, action) => {
  if (action.type === 'add') return { ...state, num: state.num + action.payload }
  return state;
}
// 得到數(shù)據(jù)對(duì)象
let store
// 開(kāi)發(fā)與生產(chǎn)環(huán)境的判斷,提高安全性
process.env.NODE_ENV === 'development'
  ?
  store = createStore(
    reducer,
    composeWithDevTools()
  )
  :
  store = createStore(
    reducer
  )
// 導(dǎo)出
export default store

6. react-redux

概述:

React-Redux 是 Redux 的官方針對(duì) React 開(kāi)發(fā)的擴(kuò)展庫(kù),默認(rèn)沒(méi)有在 React 項(xiàng)目中安裝,需要手動(dòng)來(lái)安裝。react-redux 是依賴于 redux,所以你必須安裝 redux。

你可以理解為 react-redux 就是 redux 給我們提供一些高階組件,能解決的問(wèn)題是:使用它以后我們不需要在每個(gè)組件中再去手動(dòng)訂閱數(shù)據(jù)的更新了,方便了 react 組件中調(diào)用 redux 中的數(shù)據(jù)。

安裝:

yarn add react-redux

使用步驟:

在程序主文件 index.js 文件中,定義 Provider。此處類似于之前跨組件通信處的 Provider 一樣,旨在讓全局的組件共享 store 中的數(shù)據(jù)。

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
// 導(dǎo)入Provider生產(chǎn)數(shù)據(jù)者組件
import { Provider } from 'react-redux'
// 導(dǎo)入數(shù)據(jù)源
import store from './store'
ReactDOM.render(
  // 包裹所有的路由
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

在組件中使用 react-redux

import React, { Component } from 'react'
// 提供一個(gè)高階組件 connect 用來(lái)把 redux 中的 state 和 action 映射到當(dāng)前組件的 props 中
import { connect } from 'react-redux'
// 此函數(shù)必須要返回一個(gè)json對(duì)象
// 函數(shù)的 state 參數(shù)就是 redux 中的 state 數(shù)據(jù)
const mapStateToProps = state => {
  return { num: state.num }
}
// mapStateToProps 函數(shù)的兩種簡(jiǎn)寫(xiě)寫(xiě)法
// const mapStateToProps = state => state
// @connect(state => state, mapDispatchToProps)
// 此函數(shù)必須要返回一個(gè)json對(duì)象
// dispatch 就是之前通過(guò) store.dispatch 的方法
const mapDispatchToProps = dispatch => {
  return {
    add(n = 1) {
      // 動(dòng)作:增加,數(shù)據(jù):n
      dispatch({ type: 'add', payload: n })
    }
  }
}
// 函數(shù)的方式可以同步也可以異步,dispatch 是你手動(dòng)在需要的地方來(lái)調(diào)用
// const mapDispatchToProps = dispatch => {
//   return {
//     add(n = 1) {
//       setTimeout(() => {
//         dispatch({ type: 'add', payload: n })
//       }, 1000)
//     }
//   }
// }
// 該函數(shù)的對(duì)象寫(xiě)法:
// 如果為對(duì)象方式則只能使用同步,不能用異步,因?yàn)樵?connect 實(shí)現(xiàn)時(shí)如果是對(duì)象,則它會(huì)主動(dòng)調(diào)用 dispatch
// 調(diào)用了 dispatch 它就立刻執(zhí)行。而如果是一個(gè)異步,則就會(huì)不符合 dispatch 要求,則報(bào)錯(cuò)
// const mapDispatchToProps = {
//   add: (n = 1) => ({ type: 'add', payload: n })
// }
// 參數(shù)1:函數(shù),把 redux 中的 state 數(shù)據(jù)映射到當(dāng)前的 props 屬性中
// 參數(shù)2:函數(shù)|對(duì)象,把你操作的 dispatch 方法映射到當(dāng)前的 props 屬性中
@connect(mapStateToProps, mapDispatchToProps)
class App extends Component {
  render() {
    console.log('props', this.props)
    return (
      <div>
        <h3>{this.props.num}</h3>
        <hr />
        <button onClick={() => this.props.add()}>++++</button>
      </div>
    )
  }
}
export default App

上面是使用裝飾器的寫(xiě)法,還有不使用裝飾器的寫(xiě)法:

我們需要將裝飾器一行注釋,并且修改導(dǎo)出方式。

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

相關(guān)文章

  • 詳解react阻止無(wú)效重渲染的多種方式

    詳解react阻止無(wú)效重渲染的多種方式

    這篇文章主要介紹了詳解react阻止無(wú)效重渲染的多種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • react跳轉(zhuǎn)后路由變了頁(yè)面沒(méi)刷新的解決

    react跳轉(zhuǎn)后路由變了頁(yè)面沒(méi)刷新的解決

    這篇文章主要介紹了react跳轉(zhuǎn)后路由變了頁(yè)面沒(méi)刷新的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • React深入分析更新的創(chuàng)建源碼

    React深入分析更新的創(chuàng)建源碼

    React組件分為函數(shù)組件與class組件;函數(shù)組件是無(wú)狀態(tài)組件,class稱為類組件;函數(shù)組件只有props,沒(méi)有自己的私有數(shù)據(jù)和生命周期函數(shù);class組件有自己私有數(shù)據(jù)(this.state)和生命周期函數(shù)
    2023-01-01
  • React實(shí)現(xiàn)控制減少useContext導(dǎo)致非必要的渲染詳解

    React實(shí)現(xiàn)控制減少useContext導(dǎo)致非必要的渲染詳解

    這篇文章主要介紹了React如何有效減少使用useContext導(dǎo)致的不必要渲染,使用useContext在改變一個(gè)數(shù)據(jù)時(shí),是通過(guò)自己逐級(jí)查找對(duì)比改變的數(shù)據(jù)然后渲染,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • React全局狀態(tài)管理的三種底層機(jī)制探究

    React全局狀態(tài)管理的三種底層機(jī)制探究

    近兩年前端技術(shù)的發(fā)展如火如荼,大量的前端項(xiàng)目都在使用或轉(zhuǎn)向 Vue 和 React 的陣營(yíng),由前端渲染頁(yè)面的單頁(yè)應(yīng)用占比也越來(lái)越高,這篇文章主要給大家介紹了關(guān)于React全局狀態(tài)管理的三種底層機(jī)制,需要的朋友可以參考下
    2021-09-09
  • react實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽(tīng)方式

    react實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽(tīng)方式

    這篇文章主要介紹了react實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽(tīng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React通過(guò)hook實(shí)現(xiàn)封裝表格常用功能

    React通過(guò)hook實(shí)現(xiàn)封裝表格常用功能

    這篇文章主要為大家詳細(xì)介紹了React通過(guò)hook封裝表格常用功能的使用,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下
    2023-12-12
  • react中的forwardRef 和memo的區(qū)別解析

    react中的forwardRef 和memo的區(qū)別解析

    forwardRef和memo是React中用于性能優(yōu)化和組件復(fù)用的兩個(gè)高階函數(shù),本文給大家介紹react中的forwardRef 和memo的區(qū)別及適用場(chǎng)景,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • 詳解React native fetch遇到的坑

    詳解React native fetch遇到的坑

    這篇文章主要介紹了詳解React native fetch遇到的坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 用React-Native+Mobx做一個(gè)迷你水果商城APP(附源碼)

    用React-Native+Mobx做一個(gè)迷你水果商城APP(附源碼)

    這篇文章主要介紹了用React-Native+Mobx做一個(gè)迷你水果商城APP,功能需要的朋友可以參考下
    2017-12-12

最新評(píng)論

黄山市| 石泉县| 林西县| 峡江县| 瓦房店市| 德昌县| 乳山市| 丹凤县| 巴彦县| 荃湾区| 蒲江县| 讷河市| 东港市| 固始县| 云浮市| 习水县| 府谷县| 民乐县| 古丈县| 福州市| 象山县| 黑龙江省| 饶平县| 房山区| 瑞安市| 平果县| 蓝山县| 浦县| 玉林市| 沂源县| 运城市| 南华县| 浦县| 沂南县| 鲁甸县| 福建省| 鲁山县| 云霄县| 平顶山市| 腾冲县| 张家界市|