react全局狀態管理_react狀態管理redux

Redux(上)

結合阮老師的技術博客,將自己吸收到的內容做了個整理:

曾經有人說過這樣一句hua : 如果你不知道是否需要Redux,那就是不需要它。

從組建層面考慮,什么樣子的需要redux;某個組件的狀態需要共享,

某個狀態需要在任何地方都可以拿到,

一個組件需要改變全局狀態,

一個組件需要改變另一個組件的狀態

一)Redux的設計思想 很重要

1)web應用是一個狀態機,試圖與狀態是一一對應的

2)所有的狀態,保存在一個對象里面(唯一數據源)

二)基本概念和 API

1、store

store就是保存數據的地方,你可以把它看成一個容器。整個應用只能有一個Store

Redux提供createStore這個函數,用來生成Store,import?{createStore}?from?'redux'

/創建一個reducer文件夾?并引入reducer

const?store?=?createStore(reducer)

export?default?store

2、state

Store對象包含所有數據。如果想得到某個時點的數據,就要對 Store 生成快照。這種時點的數據集合,就叫做 State。

當前時刻的 State,可以通過store.getState()拿到。import?{?createStore?}?from?'redux';

const?store?=?createStore(fn);

const?state?=?store.getState();

Redux 規定, 一個 State 對應一個 View。只要 State 相同,View 就相同。你知道 State,就知道 View 是什么樣,反之亦然。

3、Action

State 的變化,會導致 View 的變化。但是,用戶接觸不到 State,只能接觸到 View。所以,State 的變化必須是 View 導致的。Action 就是 View 發出的通知,表示 State 應該要發生變化了。

Action 是一個對象。其中的type屬性是必須的,表示 Action 的名稱。其他屬性可以自由設置,社區有一個規范可以參考。const?action?=?{

type:?'ADD_TODO',

payload:?'Learn?Redux'

};

上面代碼中,Action 的名稱是ADD_TODO,它攜帶的信息是字符串Learn Redux。

可以這樣理解,Action 描述當前發生的事情。改變 State 的唯一辦法,就是使用 Action。它會運送數據到 Store。

4、Action Creator

View 要發送多少種消息,就會有多少種 Action。如果都手寫,會很麻煩。可以定義一個函數來生成 Action,這個函數就叫 Action Creator。const?ADD_TODO?=?'添加?TODO';

function?addTodo(text)?{

return?{

type:?ADD_TODO,

text

}

}

const?action?=?addTodo('Learn?Redux');

上面代碼中,addTodo函數就是一個 Action Creator。

5、store.dispatch()

store.dispatch()是 View 發出 Action 的唯一方法。import?{?createStore?}?from?'redux';

const?store?=?createStore(fn);

store.dispatch({

type:?'ADD_TODO',

payload:?'Learn?Redux'

});

上面代碼中,store.dispatch接受一個 Action 對象作為參數,將它發送出去。

結合 Action Creator,這段代碼可以改寫如下。store.dispatch(addTodo('Learn?Redux'));?

6、Reducer

Store 收到 Action 以后,必須給出一個新的 State,這樣 View 才會發生變化。這種 State 的計算過程就叫做 Reducer。

Reducer 是一個函數,它接受 Action 和當前 State 作為參數,返回一個新的 State。const?reducer?=?function?(state,?action)?{

//?...

return?new_state;

};

整個應用的初始狀態,可以作為 State 的默認值。下面是一個實際的例子。const?defaultState?=?0;

const?reducer?=?(state?=?defaultState,?action)?=>?{

switch?(action.type)?{

case?'ADD':

return?state?+?action.payload;

default:

return?state;

}

};

const?state?=?reducer(1,?{

type:?'ADD',

payload:?2

});

上面代碼中,reducer函數收到名為ADD的 Action 以后,就返回一個新的 State,作為加法的計算結果。其他運算的邏輯(比如減法),也可以根據 Action 的不同來實現。

實際應用中,Reducer 函數不用像上面這樣手動調用,store.dispatch方法會觸發 Reducer 的自動執行。為此,Store 需要知道 Reducer 函數,做法就是在生成 Store 的時候,將 Reducer 傳入createStore方法。import?{?createStore?}?from?'redux';

const?store?=?createStore(reducer);

上面代碼中,createStore接受 Reducer 作為參數,生成一個新的 Store。以后每當store.dispatch發送過來一個新的 Action,就會自動調用 Reducer,得到新的 State。

7、store.subscribe()

Store 允許使用store.subscribe方法設置監聽函數,一旦 State 發生變化,就自動執行這個函數。import?{?createStore?}?from?'redux';

const?store?=?createStore(reducer);

store.subscribe(listener);

顯然,只要把 View 的更新函數(對于 React 項目,就是組件的render方法或setState方法)放入listen,就會實現 View 的自動渲染。

store.subscribe方法返回一個函數,調用這個函數就可以解除監聽。let?unsubscribe?=?store.subscribe(()?=>

console.log(store.getState())

);

unsubscribe();?

三)舉個例子

簡單計數器的例子:麻雀雖小,五臟俱全

主要是觀察store中的三個方法:

1、store.getState(); 在視圖層通過該方法取到存儲在store中的state。下圖中23、24行代碼

2、store.dispatch(); 在視圖層通過該方法發送一個actions,去通知reducers去改變state值。下面的reducer函數

3、store.subscribe(); 通過該函數設置監聽,一旦state發生改變,就會調用該函數,重新渲染視圖層,如下面的31行代碼

很明顯 redux中 reducer和Action Creators都是一個純函數,這就要求他們不允許:直接修改 state 參數對象

請求 API

調用不純的函數,比如?Data.now()?Math.random()

那這樣的話,異步操作是如何實現的呢,這就需要借助中間件redux-thunk或者redux-sage在發出action到reducer接收到action之間來執行異步操作。(redux-thunk、redux-sage介紹參考簡書)const?Counter?=?({?value,?onIncrement,?onDecrement?})?=>?(

{value}

+

-

);

const?reducer?=?(state?=?0,?action)?=>?{

switch?(action.type)?{

case?'INCREMENT':?return?state?+?1;

case?'DECREMENT':?return?state?-?1;

default:?return?state;

}

};

const?store?=?createStore(reducer);

const?render?=?()?=>?{

ReactDOM.render(

value={store.getState()}

onIncrement={()?=>?store.dispatch({type:?'INCREMENT'})}

onDecrement={()?=>?store.dispatch({type:?'DECREMENT'})}

/>,

document.getElementById('root')

);

};

render();

store.subscribe(render);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530171.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530171.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530171.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

edges2shoes數據集下載_edges2cats

edges2cats是一款十分有趣味的生成貓咪的游戲,在這款游戲是以多種不同的圖形相結合,來生成你所想要生成的畫面,游戲的玩法非常的有趣,感興趣的可以試玩哦!edges2cats游戲怎么玩 玩法介紹首先清除畫面,根據你…

單片機機器周期怎么計算公式_單片機定時器周期計算公式

定時器是單片機的重要功能模塊之一,在檢測、控制領域有廣泛應用。定時器常用作定時時鐘,以實現定時檢測,定時響應、定時控制,并且可以產生ms寬的脈沖信號,驅動步進電機。定時和計數的最終功能都是通過計數實現&#xf…

mac 下mysql工具_mysql之工具的使用總結(mac版本)

13.mysql Mac終端操作12.MySql在Mac上的安裝與配置詳解;11.mac下安裝mysql5.7.18,連接出現Access denied for user rootlocalhost (using password: YES)13.mysql Mac終端操作1.啟動mysql :brew services start mysql2.登陸mysql : mysql -u…

sqoop同步時間戳到mysql_在sqoop導入中使用24小時時間戳

我想從使用自由格式查詢的oracle導入數據,并且需要以24小時格式存儲時間戳。在sqoop導入中使用24小時時間戳sqoop import --connect jdbc:oracle:thin:(server credntials) \--username ***** --password ***** \--query "select emp_uid, emp_name, salary, t…

mysql權限系統的工作原理_Mysql權限系統工作原理

MySQL權限系統保證所有的用戶可以嚴格地做他們假定被允許做的事情。當你連接一個MySQL服務器時, 你的身份由你從那連接的主機和你指定的用戶名來決定,系統根據你的身份和你想做什么來授予權限。MySQL在認定身份中考慮你的主機名和用戶名字,是…

mysql日志文件的類型和作用_Mysql日志文件和日志類型介紹_MySQL

日志文件類型MySQL有幾個不同的日志文件,可以幫助你找出mysqld內部發生的事情:日志文件記入文件中的信息類型錯誤日志記錄啟動、運行或停止mysqld時出現的問題。查詢日志記錄建立的客戶端連接和執行的語句。更新日志記錄更改數據的語句。不贊成使用該日志…

ruby mysql 驅動_windows下Rails安裝MySql驅動的配置

1.安裝ruby這我就不廢話了,安裝很簡單,網上資料也很多。安裝完后再環境變量path里加入D:ruby\bin(視你的安裝路徑了)安裝完后在命令行輸入ruby -v, 會顯示版本號,表示安裝成功,我的版本號是1.8.62.安裝rails我建議去官…

cross join 一張表沒有值關聯不出來數據_你是否還在對left join、right join和join有困擾呢?...

說到SQL,很多人可能用了挺久,但依然有個問題一直困擾著,那就是 left join、 join、 right join和 inner join等等各種 join的區別。網上搜,最常見的就是一張圖解圖,如下:接下來就來實際自己動手實驗&#x…

MySQL如何修改表的儲存方式_修改mysql默認存儲引擎的方法

修改mysql默認存儲引擎的方法,供大家學習參考。先來了解一下mysql存儲引擎:mysql服務器采用了模塊化風格,各部分之間保持相對獨立,尤其體現在存儲架構上。存儲引擎負責管理數據存儲,以及mysql的索引管理。通過定義的AP…

前端判斷是否安裝桌面應用_前端開發人員的桌面應用神器 Electron

01為什么用 JavaScript 來開發桌面應用?曾經的 JavaScript 脆弱、簡陋、甚至有被邊緣化的危險,不過 JavaScript 在經過了兩次飛躍后(以 V8 為首的 JavaScript 引擎和 Node.js 的問世),不再受人欺負,早已升級…

mysql 導出csv 多列_從包含300多列的csv,txt或xls文件創建MySQL表

你可以用一些langague C ,PHP解析txt文件......然后構建一個請求并執行它。PHP和PDO :: module將使這個最簡單。我不知道某個程序是否已經完成這項工作。這是一個解決方案。如果您選擇這樣做并遇到麻煩,歡迎您。每個stackoverflow成員都會幫助您。編輯&a…

mysql error 1594_【MySQL】解決mysql的 1594 錯誤-阿里云開發者社區

對于主從架構的mysql,當發生主機斷電或者其他原因異常crash的時候, slave的容易發生讀取binlog出錯的問題,最常見的是show slave status \G;Master_Log_File: mysql-bin.000029Read_Master_Log_Pos: 3154083Relay_Log_File: relay-bin.000478Relay_Log_Pos: 633Rel…

mysql innodb文件_MySQL的InnoDB文件介紹

MySQL一個顯著的特點是其可插拔的存儲引擎,因此MySQL文件分為兩種,一種是和MySQL數據庫本身相關 的文件,一種是和存儲引擎相關的文件。本文主要介紹和InnoDB存儲引擎相關的文件。表空間文件InnoDB在存儲上也模仿了Oracle的設計,數…

python中與label類似的控件是_python中tkinter的使用(控件整理)(一)

1、使用tkinter.Tk() 生成主窗口(windowtkinter.Tk()):window.title(標題名)修改框體的名字,也可在創建時使用className參數來命名;window.resizable(0,0)框體大小可調性,分別表示x,y方向的可變性;1表示可變,0表示不可…

jdbc dao 工具類mysql_Java基于JDBC實現事務,銀行轉賬及貨物進出庫功能示例

本文實例講述了Java基于JDBC實現事務,銀行轉賬及貨物進出庫功能。分享給大家供大家參考,具體如下:1. 轉賬業務轉賬必須執行2個sql語句(update更新)都成功的情況下,提交事務,如果有一個失敗,則2個都回滾事務…

冒險島單機版mysql_冒險島單機版

這款《冒險島單機版》經驗是盛大冒險島的100倍?最新盛大地圖及BOSS,甚至包括盛大沒有地圖BOSS及現金裝備,地圖包括新加坡,馬來西亞,臺灣,可口可樂城,鬧鬼宅邸,暹羅等等?。25駕坐騎&#xff0c…

python與html5搭建聊天室_html5 websocket 新版協議聊天室 服務端(python版)

網上找了很多代碼都是舊版協議的,研究了很久終于弄清楚了 現在發個用新版協議寫的服務端代碼出來(這個代碼是從網上舊版協議改過來的)最要就是握手協議和發送接受字符的方式變了# incodingutf-8import socketimport structimport hashlibimport threading,randomimp…

mysql數據庫開發筆記_MySQL數據庫生成數據庫說明文檔

在半年多前為一個MySQL數據庫生成過數據庫說明文檔,今天要重新生成一份,但是發現完全不記得當時是怎么生成的,只能在網上搜索重來一遍,所以今天特意把這個過程記錄一下。一、安裝使用MySQL數據庫表結構導出器DBExportDoc V1.0 For…

java 字符串緩沖區_詳解Java中字符串緩沖區StringBuffer類的使用

StringBuffer 是一個線程安全的可變的字符序列。它繼承于AbstractStringBuilder,實現了CharSequence接口。StringBuilder 也是繼承于AbstractStringBuilder的子類;但是,StringBuilder和StringBuffer不同,前者是非線程安全的&#…

rabbitmq java文檔_RabbitMQ文檔翻譯——Hello World!(上)

文章主要翻譯自RabbitMQ官方文檔,主要是為了練習英語翻譯,順便學習一下RabbitMQ😶其中也記錄了一些爬過的坑IntroductionRabbitMQ is a message broker. The principal idea is pretty simple: it accepts and forwards messages. You can th…