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

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

 更新時(shí)間:2022年08月31日 15:06:57   作者:小綿楊Yancy  
redux是redux官方react綁定庫(kù),能夠使react組件從redux store中讀取數(shù)據(jù),并且向store分發(fā)actions以此來(lái)更新數(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),如激活的路由,被選中的標(biāo)簽,是否顯示加載動(dòng)效或者分頁(yè)器等等。

二、Redux的組成

2.1 store

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

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

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

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

2.2 state

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

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

2.3 action

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

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

2.4 reducer

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

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

const store = createStore(reducer);

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

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

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

三、三大原則

Redux 可以用這三個(gè)基本原則來(lái)描述:

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

整個(gè)應(yīng)用的 state 被儲(chǔ)存在一棵 object tree 中,并且這個(gè) object tree 只存在于唯一一個(gè) 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 是一個(gè)用于描述已發(fā)生事件的普通對(duì)象。

這樣確保了視圖和網(wǎng)絡(luò)請(qǐng)求都不能直接修改 state,相反它們只能表達(dá)想要修改的意圖。因?yàn)樗械男薷亩急患谢幚?,且?yán)格按照一個(gè)接一個(gè)的順序執(zhí)行,因此不用擔(dān)心競(jìng)態(tài)條件(race condition)的出現(xiàn)。 Action 就是普通對(duì)象而已,因此它們可以被日志打印、序列化、儲(chǔ)存、后期調(diào)試或測(cè)試時(shí)回放出來(lái)。

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

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

例如完成一個(gè)新增todo的功能:

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

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

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

這里使用了擴(kuò)展運(yùn)算符(…)將數(shù)組展開(kāi)然后和新增的todo合并,對(duì)象同樣可以使用擴(kuò)展運(yùn)算符達(dá)到新增屬性的目的。

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

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

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

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: "睡覺(jué)??",
    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;

詳細(xì)代碼地址:

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

五、react-redux

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

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

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

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

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

5.1 connect方法

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

import {connect} from 'react-redux'
const Counter = (props) => {
    return (
        <div>
            <p>計(jì)數(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
    }
}
//進(jìn)行觸發(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 是一個(gè)函數(shù),它的作用就是建立一個(gè)從 state對(duì)象(外部)到 UI 組件 props對(duì)象的映射關(guān)系。該函數(shù)會(huì)訂閱 整個(gè)應(yīng)用的 store,每當(dāng) state 更新的時(shí)候,就會(huì)自動(dòng)執(zhí)行,重新計(jì)算 UI 組件的參數(shù),從而觸發(fā) UI 組件的重新渲染。還可以使用第二個(gè)參數(shù)(可選),代表容器組件的 props 對(duì)象
  • mapDispathToProps:mapDispatchToProps 是 connect 函數(shù)的第二個(gè)參數(shù),用來(lái)建立 UI 組件的參數(shù)到 store.dispatch 方法的映射。
  • Counter:需要變成容器組件的UI組件,也就是需要連接store的組件。

5.2 Provider組件

  • 使用 connect 方法生成容器組件以后,需要讓容器組件拿到 state 對(duì)象,才能生成 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>
)

此時(shí)Counter組件和ShowCounter組件都可以拿到state。

ShowCounter.jsx:

import React from "react";
import {connect} from "react-redux";
const ShowCounter = (props) => {
    return (
        <div>
            <p>來(lái)自計(jì)數(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 搭建React?Native熱更新平臺(tái)的詳細(xì)過(guò)程

    搭建React?Native熱更新平臺(tái)的詳細(xì)過(guò)程

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

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

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

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

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

    React路由的history對(duì)象的插件history的使用解讀

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

    詳解React?Native項(xiàng)目中啟用Hermes引擎

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

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

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

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

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

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

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

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

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

    詳細(xì)聊聊React源碼中的位運(yùn)算技巧

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

最新評(píng)論