您好,登錄后才能下訂單哦!
這篇“在React中怎么處理數據流”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“在React中怎么處理數據流”文章吧。
背景
相信大家在項目開發中,在頁面較復雜的情況下,往往會遇到一個問題,就是在頁面組件之間通信會非常困難。
比如說一個商品列表和一個已添加商品列表:
假如這兩個列表是獨立的兩個組件,它們會共享一個數據 “被選中的商品”,在商品列表選中一個商品,會影響已添加商品列表,在已添加列表中刪除一個商品,同樣會影響商品列表的選中狀態。
它們兩個是兄弟組件,在沒有數據流框架的幫助下,在組件內數據有變化的時候,只能通過父組件傳輸數據,往往會有 onSelectedDataChange 這種函數出現,在這種情況下,還尚且能忍受,如果組件嵌套較深的話,那痛苦可以想象一下,所以才有解決數據流的各種框架的出現。
本質分析
我們知道 React 是 MVC 里的 V,并且是數據驅動視圖的,簡單來說,就是數據 => 視圖,視圖是基于數據的渲染結果:
V = f(M)
數據有更新的時候,在進入渲染之前,會先生成 Virtual DOM,前后進行對比,有變化才進行真正的渲染。
V + ΔV = f(M + ΔM)
數據驅動視圖變化有兩種方式,一種是 setState,改變頁面的 state,一種是觸發 props 的變化。
我們知道數據是不會自己改變,那么肯定是有“外力”去推動,往往是遠程請求數據回來或者是 UI 上的交互行為,我們統稱這些行為叫 action:
ΔM = perform(action)
每一個 action 都會去改變數據,那么視圖得到的數據(state)就是所有 action 疊加起來的變更,
state = actions.reduce(reducer, initState)
所以真實的場景會出現如下或更復雜的情況:
問題就出在,更新數據比較麻煩,混亂,每次要更新數據,都要一層層傳遞,在頁面交互復雜的情況下,無法對數據進行管控。
有沒有一種方式,有個集中的地方去管理數據,集中處理數據的接收,修改和分發?答案顯然是有的,數據流框架就是做這個事情,熟悉 Redux 的話,就知道其實上面講的就是 Redux 的核心理念,它和 React 的數據驅動原理是相匹配的。
數據流框架
Redux
數據流框架目前占主要地位的還是 Redux,它提供一個全局 Store 處理應用數據的接收,修改和分發。
它的原理比較簡單,View 里面有任何交互行為需要改變數據,首先要發一個 action,這個 action 被 Store 接收并交給對應的 reducer 處理,處理完后把更新后的數據傳遞給 View。Redux 不依賴于任何框架,它只是定義一種方式控制數據的流轉,可以應用于任何場景。
雖然定義了一套數據流轉的方式,但真正使用上會有不少問題,我個人總結主要是兩個問題:
定義過于繁瑣,文件多,容易造成思維跳躍。
異步流的處理沒有優雅的方案。
我們來看看寫一個數據請求的例子,這是非常典型的案例:
actions.js
export const FETCH_DATA_START = 'FETCH_DATA_START';
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
export const FETCH_DATA_ERROR = 'FETCH_DATA_ERROR';
export function fetchData() {
return dispatch => {
dispatch(fetchDataStart());
axios.get('xxx').then((data) => {
dispatch(fetchDataSuccess(data));
}).catch((error) => {
dispatch(fetchDataError(error));
});
};
}
export function fetchDataStart() {
return {
type: FETCH_DATA_START,
}
}
...FETCH_DATA_SUCCESS
...FETCH_DATA_ERROR
reducer.js
import { FETCH_DATA_START, FETCH_DATA_SUCCESS, FETCH_DATA_ERROR } from 'actions.js';
export default (state = { data: null }, action) => {
switch (action.type) {
case FETCH_DATA_START:
...
case FETCH_DATA_SUCCESS:
...
case FETCH_DATA_ERROR:
...
default:
return state
}
}
view.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from 'reducer.js';
import { fetchData } from 'actions.js';
const store = createStore(reducer, applyMiddleware(thunk));
store.dispatch(fetchData());
第一個問題,發一個請求,因為需要托管請求的所有狀態,所以需要定義很多的 action,這時很容易會繞暈,就算有人嘗試把這些狀態再封裝抽象,也會充斥著一堆模板代碼。有人會挑戰說,雖然一開始是比較麻煩,繁瑣,但對項目可維護性,擴展性都比較友好,我不太認同這樣的說法,目前還算簡單,真正業務邏輯復雜的情況下,會顯得更惡心,效率低且閱讀體驗差,相信大家也寫過或看過這樣的代碼,后面自己看回來,需要在 actions 文件搜索一下 action 的名稱,reducer 文件查詢一下,繞一圈才慢慢看懂。
第二個問題,按照官方推薦使用 redux-thunk 實現異步 action 的方法,只要在 action 里返回一個函數即可,這對有強迫癥的人來說,簡直受不了,actions 文件顯得它很不純,本來它只是來定義 action,卻竟然要夾雜著數據請求,甚至 UI 上的交互。
以上就是關于“在React中怎么處理數據流”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。