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

React狀態(tài)管理Redux原理與介紹

 更新時間:2022年08月31日 15:06:57   作者:小綿楊Yancy  
redux是redux官方react綁定庫,能夠使react組件從redux store中讀取數(shù)據(jù),并且向store分發(fā)actions以此來更新數(shù)據(jù),這篇文章主要介紹了react-redux的設(shè)置,需要的朋友可以參考下

一、Redux

和vuex一樣,redux的出現(xiàn)是為了管理web應(yīng)用的公共狀態(tài)。

這些 state 可能包括服務(wù)器響應(yīng)、緩存數(shù)據(jù)、本地生成尚未持久化到服務(wù)器的數(shù)據(jù),也包括 UI 狀態(tài),如激活的路由,被選中的標簽,是否顯示加載動效或者分頁器等等。

二、Redux的組成

2.1 store

store 就是保存數(shù)據(jù)的地方,整個應(yīng)用只能有一個 store,可以理解為一個存儲數(shù)據(jù)的倉庫。

redux 提供 createStore 這個函數(shù),用來創(chuàng)建一個store 以存放整個應(yīng)用的 state:

import { createStore } from 'redux';
const store = createStore(reducer, [preloadedState], [enhancer]);

可以看到,createStore 接受 reducer初始 state(可選)和增強器(可選)作為參數(shù),返回一個新的 store 對象.

2.2 state

state就是store 對象包含所有數(shù)據(jù),如果要獲取當前時刻的 state,可以通過 store.getState() 方法拿到:

import { createStore } from 'redux';
const store = createStore(reducer, [preloadedState], [enhancer]);
const state = store.getState();

2.3 action

  • state 的變化,會導(dǎo)致視圖的變化。但是,用戶接觸不到 state,只能接觸到視圖。所以,state 的變化必須是由視圖發(fā)起的。
  • action 就是視圖發(fā)出的通知,通知store此時的 state 應(yīng)該要發(fā)生變化了。
  • action 是一個對象。其中的 type屬性是必須的,表示 action 的名稱。其他屬性可以自由設(shè)置,社區(qū)有一個規(guī)范可以參考:
const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux' // 可選屬性 可自定義名稱
};

所以action可以理解為視圖層向store發(fā)送的一個命令(通知),它包含了需要執(zhí)行的事件(type屬性)以及傳遞的數(shù)據(jù)(自定義屬性)。

2.4 reducer

  • store 收到 action 以后,必須給出一個新的 state,這樣視圖才會進行更新。state 的計算(更新)過程則是通過reducer 實現(xiàn)。
  • reducer 是一個函數(shù),它接受 action 和當前 state 作為參數(shù),返回一個新的 state:
const reducer = function (state = initState, action) {
  // ...
  return new_state;
};

創(chuàng)建store時,第一個參數(shù)就是reducer:

const store = createStore(reducer);

那么如何向store發(fā)送action呢?

store.dispatch({
  type: 'ADD_TODO',
  payload: 'Learn Redux'
});

store對象擁有dispath方法發(fā)送action,參數(shù)就是需要傳遞的action對象,然后reducer接收到action并處理,返回新的state,視圖自動更新。

三、三大原則

Redux 可以用這三個基本原則來描述:

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

整個應(yīng)用的 state 被儲存在一棵 object tree 中,并且這個 object tree 只存在于唯一一個 store 中。

console.log(store.getState())
/* 輸出
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/

3.2 State只讀

唯一改變 state 的方法就是觸發(fā) action,action 是一個用于描述已發(fā)生事件的普通對象。

這樣確保了視圖和網(wǎng)絡(luò)請求都不能直接修改 state,相反它們只能表達想要修改的意圖。因為所有的修改都被集中化處理,且嚴格按照一個接一個的順序執(zhí)行,因此不用擔(dān)心競態(tài)條件(race condition)的出現(xiàn)。 Action 就是普通對象而已,因此它們可以被日志打印、序列化、儲存、后期調(diào)試或測試時回放出來。

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})
store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

所以返回新的state時不能直接修改參數(shù)state,而是在不修改參數(shù)state的基礎(chǔ)上返回新的state。

例如完成一個新增todo的功能:

case 'ADD_TODO':
      return state.push({
          text: action.text,
          completed: false
        })

這樣是不會生效的,應(yīng)為這樣直接修改了state的值,正確的做法應(yīng)該是:

 case 'ADD_TODO':
	    return [
	      ...state,
	      {
	        text: action.text,
	        completed: false
	      }
	    ]

這里使用了擴展運算符(…)將數(shù)組展開然后和新增的todo合并,對象同樣可以使用擴展運算符達到新增屬性的目的。

3.3 使用純函數(shù)修改State

為了描述 action 如何改變 state tree ,你需要編寫 reducers。

Reducer 只是一些純函數(shù),它接收先前的 stateaction,并返回新的 state。剛開始你可以只有一個 reducer,隨著應(yīng)用變大,你可以把它拆成多個小的 reducers,分別獨立地操作 state tree 的不同部分,因為 reducer 只是函數(shù),你可以控制它們被調(diào)用的順序,傳入附加數(shù)據(jù),甚至編寫可復(fù)用的 reducer 來處理一些通用任務(wù),如分頁器。

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}
function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}
import { combineReducers, createStore } from 'redux'
//合并reducer
let reducer = combineReducers({ visibilityFilter, todos })
//利用reducer創(chuàng)建store
let store = createStore(reducer)

四、基于Redux的TodoList

效果:

todes的reducer:

const initTodos = [
  {
    id: 1,
    text: "睡覺??",
    completed: false,
  },
  {
    id: 2,
    text: "吃飯??",
    completed: false,
  },
  {
    id: 3,
    text: "打豆豆??",
    completed: true,
  },
];
let nextTodoID = 4;
const todos = (state = initTodos, action) => {
  switch (action.type) {
    case "ADD_TODO":
      return [
        ...state,
        {
          id: nextTodoID++,
          text: action.text,
          completed: false,
        },
      ];
    case "TOGGLE_TODO":
      return state.map((todo) =>
        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
      );
    default:
      return state;
  }
};
export default todos;

filter的reducer:

const visibilityFilter = (state = "SHOW_ALL", action) => {
  switch (action.type) {
    case "SET_VISIBILITY_FILTER":
      return action.filter;
    default:
      return state;
  }
};
export default visibilityFilter;

詳細代碼地址:

https://github.com/YancyZhang30/react-redux-todos.git

五、react-redux

redux 并不是react專有的,其本身是一個可以結(jié)合 react,vue,angular 甚至是原生 javaScript 應(yīng)用使用的狀態(tài)庫。

react-redux是react官方提供了 react的redux適配庫(這個庫是可以選用的,也可以只用redux),使得我們能夠更好地在react應(yīng)用中使用redux來進行全局狀態(tài)管理,使用react-redux主要是為了解決組件每次使用store中的數(shù)據(jù)時都必須先使用store.getState()來獲取state,然后必須使用store.subscribe()進行訂閱的問題。

react-redux 將所有組件分成 UI 組件和容器組件兩大類:

1、 UI 組件只負責(zé) UI 的呈現(xiàn),不含有狀態(tài)(this.state),所有數(shù)據(jù)都由 this.props 提供,且不使用任何 redux 的 API。

2、容器組件負責(zé)管理數(shù)據(jù)和業(yè)務(wù)邏輯,含有狀態(tài)(this.state),可使用 redux 的 API。

5.1 connect方法

react-redux 提供了 connect 方法,用于將 UI 組件生成容器組件,所以如果組件想要使用store中的state,就必須先使用connect方法與store進行連接:

import {connect} from 'react-redux'
const Counter = (props) => {
    return (
        <div>
            <p>計數(shù)器: {props.num}</p>
            <div>
                <button onClick={props.increatement}>加</button> | <button onClick={props.decreate}>減</button><br/>
            </div>
        </div>
    )
}
//讀取數(shù)據(jù)
const mapStateToProps=(state)=>{
    return{
        num:state
    }
}
//進行觸發(fā)action
const mapDispathToProps=(dispatch)=>{
    return {
        increatement:()=>{dispatch(
            {
                type:"inCreateNum",
                num:10
            }
        )},
        decreate:()=>{dispatch(
            {
                type:"descment",
                num:10
            }
        )}
    }
}
// connect將組件與store連接。connect里的參數(shù)順序不能顛倒
export default connect(mapStateToProps,mapDispathToProps)(Counter)

connect(mapStateToProps,mapDispathToProps)(Counter)中:

  • mapStateToProps:mapStateToProps 是一個函數(shù),它的作用就是建立一個從 state對象(外部)到 UI 組件 props對象的映射關(guān)系。該函數(shù)會訂閱 整個應(yīng)用的 store,每當 state 更新的時候,就會自動執(zhí)行,重新計算 UI 組件的參數(shù),從而觸發(fā) UI 組件的重新渲染。還可以使用第二個參數(shù)(可選),代表容器組件的 props 對象
  • mapDispathToProps:mapDispatchToProps 是 connect 函數(shù)的第二個參數(shù),用來建立 UI 組件的參數(shù)到 store.dispatch 方法的映射。
  • Counter:需要變成容器組件的UI組件,也就是需要連接store的組件。

5.2 Provider組件

  • 使用 connect 方法生成容器組件以后,需要讓容器組件拿到 state 對象,才能生成 UI 組件 的參數(shù)。
  • react-redux提供了 Provider 組件,可以讓容器組件拿到 state,注意只有被Provider組件包含的組件才能拿到state。

main.jsx:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import Counter from "./Counter";
import ShowCounter from "./ShowCounter";
import reducer from "./store/counter";
import { legacy_createStore as createStore } from "redux";
const store = createStore(reducer);
ReactDOM.createRoot(document.getElementById('root')).render(
    <Provider store={store}>
        <React.StrictMode>
            <Counter></Counter>
            <ShowCounter></ShowCounter>
        </React.StrictMode>
    </Provider>
)

此時Counter組件和ShowCounter組件都可以拿到state。

ShowCounter.jsx:

import React from "react";
import {connect} from "react-redux";
const ShowCounter = (props) => {
    return (
        <div>
            <p>來自計數(shù)器的數(shù)據(jù):<span style={{color: 'red'}}>{props.num}</span></p>
        </div>
    )
}
//讀取數(shù)據(jù)
const mapStateToProps=(state)=>{
    return{
        num:state
    }
}
// connect將組件與store連接。connect里的參數(shù)順序不能顛倒
export default connect(mapStateToProps)(ShowCounter)

由于ShowCounter組件并不需要修改store,所以mapDispathToProps參數(shù)可以直接省略了。

效果:

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

相關(guān)文章

  • 搭建React?Native熱更新平臺的詳細過程

    搭建React?Native熱更新平臺的詳細過程

    這篇文章主要介紹了搭建React?Native熱更新平臺,要實現(xiàn)?React?Native?熱更新功能,有四種思路?Code?Push、Pushy、Expo?和自研,感興趣的朋友一起通過本文學(xué)習(xí)吧
    2022-05-05
  • React實現(xiàn)antdM的級聯(lián)菜單實例

    React實現(xiàn)antdM的級聯(lián)菜單實例

    這篇文章主要為大家介紹了React實現(xiàn)antdM的級聯(lián)菜單實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • React 項目中動態(tài)設(shè)置環(huán)境變量

    React 項目中動態(tài)設(shè)置環(huán)境變量

    本文主要介紹了React 項目中動態(tài)設(shè)置環(huán)境變量,本文將介紹兩種常用的方法,使用 dotenv 庫和通過命令行參數(shù)傳遞環(huán)境變量,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • React路由的history對象的插件history的使用解讀

    React路由的history對象的插件history的使用解讀

    這篇文章主要介紹了React路由的history對象的插件history的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 詳解React?Native項目中啟用Hermes引擎

    詳解React?Native項目中啟用Hermes引擎

    這篇文章主要為大家介紹了React?Native項目中啟用Hermes引擎實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • React路由參數(shù)傳遞與嵌套路由的實現(xiàn)詳細講解

    React路由參數(shù)傳遞與嵌套路由的實現(xiàn)詳細講解

    這篇文章主要介紹了React路由參數(shù)傳遞與嵌套路由的實現(xiàn),嵌套路由原則是可以無限嵌套,但是必須要讓使用二級路由的一級路由匹配到,否則不顯示,需要的朋友可以參考一下
    2022-09-09
  • react開發(fā)教程之React 組件之間的通信方式

    react開發(fā)教程之React 組件之間的通信方式

    本篇文章主要介紹了react開發(fā)教程之React組件通信詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • React通過hook實現(xiàn)封裝表格常用功能

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

    這篇文章主要為大家詳細介紹了React通過hook封裝表格常用功能的使用,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2023-12-12
  • React源碼state計算流程和優(yōu)先級實例解析

    React源碼state計算流程和優(yōu)先級實例解析

    這篇文章主要為大家介紹了React源碼state計算流程和優(yōu)先級實例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 詳細聊聊React源碼中的位運算技巧

    詳細聊聊React源碼中的位運算技巧

    眾所周知在React中,主要用到3種位運算符 —— 按位與、按位或、按位非,下面這篇文章主要給大家介紹了關(guān)于React源碼中的位運算技巧的相關(guān)資料,需要的朋友可以參考下
    2021-10-10

最新評論