摘要:首發自我的博客,歡迎注如要運行本文的代碼,請先確認自己的版本已支持出來已經有段時間了,本文不對的具體用法作介紹,而是使用實現一個簡易的基于的使用實現初版自帶了供我們使用,它接受兩個參數,一是函數,二是初始,并返回和函數,如下這個函數自己實現
首發自我的github博客,歡迎star
注:如要運行本文的代碼,請先確認自己的react版本已支持hooks
react hooks出來已經有段時間了,本文不對hooks的具體用法作介紹,而是使用hooks實現一個簡易的基于context的redux
使用useReducer實現初版reduxReact hooks自帶了useReducer供我們使用,它接受兩個參數,一是reducer函數,二是初始state,并返回state和dispatch函數,如下
const [state, dispatch] = useReducer(reducer, initialState);
這個函數自己實現的話也不難,如下:
const useMyReducer = (reducer, initialState) => { const [state, setState] = useState(initialState); const dispatch = action => { const newState = reducer(action, state); setState(newState); }; return [state, dispatch]; };
即將initialState作為state的初始狀態傳入useState,dispatch則是一個函數,它會將接受的action和state傳給reducer,并獲取reducer的返回值賦給state
我們先利用useReducer實現一個計數器的簡單頁面
reducer函數和initialState如下:
const initialState = { count: 0 }; const reducer = (state, action) => { switch (action.type) { case "increase": return { ...state, count: state.count + 1 }; case "decrease": return { ...state, count: state.count - 1 }; default: return state; } };
計數器組件:
const Demo = () => { const [state, dispatch] = useReducer(reducer, initialState); return (counter:{state.count}); };
這就是初版的redux了,但這個redux有些問題,就是它的state和dispatch是屬于自己的,其他組件并不能拿到,也就是說,如果我們的頁面有兩個Demo組件,它們的state是各自獨立,互不影響的
將state和dispatch存在context中為了解決上述問題,我們必須擁有一個全局狀態,并將state和dispatch放入這個全局狀態中。這里,我們選用context作為我們的全局狀態,context在舊版React中不推薦使用,但在改進之后,官方開始推薦大家使用
我們先創建一個context:
const context = React.createContext();
為了各個組件都能拿到context的數據,我們需要有一個Provider組件包在最外層:
const Provider = props => { const [state, dispatch] = useReducer(reducer, initialState); return ({props.children} ); };
我們將useReducer返回的state、dispatch傳入context.Provider中,讓它的children都能拿到
然后,我們像下面一樣用Provider包在組件外層:
我們刪去計數器Demo組件中的:
const [state, dispatch] = useReducer(reducer, initialState);
加上通過useContext函數拿到context上的數據:
const { state, dispatch } = useContext(context);
要注意的是,傳入useContext函數的context必須是我們之前通過React.createContext()創建的context
這樣,即使是兩個Demo組件,它們也是共用一份數據了
解決異步的問題很顯然,現在的context-redux和單純的redux一樣,只能dispatch一個對象,也就是說,這個dispatch操作是同步的,如果我們要做異步的操作呢?很簡單,我們借鑒redux-thunk的方法,讓dispatch可以接受函數參數
改造Provider函數組件如下:
const Provider = props => { const [state, origin_dispatch] = useReducer(reducer, initialState); const dispatch = action => { if (typeof action === "function") { return action(origin_dispatch); } return origin_dispatch(action); }; return ({props.children} ); };
我們將userReducer函數返回的原始dispath命名為origin_dispatch,自定義dispatch函數,當action為函數的時候,我們執行action函數,并將origin_dispatch當作參數傳進去;action不是函數,直接調用origin_dispatch,不做處理
我們測試一下:
const sleep = wait => { return new Promise(resolve => { setTimeout(() => resolve(), wait); }); }; const increaseCount = async dispatch => { await sleep(1000); dispatch({ type: "increase" }); };
increaseCount是一個異步函數,我們將它當作參數傳入我們封裝的新dispatch中,點擊increase按鈕,1s之后,計數器的數字加1,至此,我們的context-redux也支持dispatch異步操作了
最后本文的代碼,我放在了自己的github上,這是傳送門
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102246.html
摘要:使用完成副作用操作,賦值給的函數會在組件渲染到屏幕之后。如此很容易產生,并且導致邏輯不一致。同時,這也是很多人將與狀態管理庫結合使用的原因之一。當我們通過的第二個數組類型參數,指明當前的依賴,就能避免不相關的執行開銷了。 前言 本文內容大部分參考了 overreacted.io 博客一文,同時結合 React Hook 官方 文章,整理并歸納一些筆記和輸出個人的一些理解 什么是 Hoo...
摘要:更容易將組件的與狀態分離。也就是只提供狀態處理方法,不會持久化狀態。大體思路是利用共享一份數據,作為的數據源。精讀帶來的約定函數必須以命名開頭,因為這樣才方便做檢查,防止用判斷包裹語句。前端精讀幫你篩選靠譜的內容。 1 引言 React Hooks 是 React 16.7.0-alpha 版本推出的新特性,想嘗試的同學安裝此版本即可。 React Hooks 要解決的問題是狀態共享,...
摘要:使用該對象,可以跟蹤屬于組件的各種元數據位。調用你的組件這意味著它知道存儲的元數據對象。下一次渲染會發生什么需要重新渲染組件由于之前已經看過這個組件,它已經有了元數據關聯。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 我們大部分 React 類組件可以保存狀態,而函數組件不能? 并且類組件具有生命周期,而函數組件卻不能...
摘要:在這種情況下,如果狀態發生變化,將再次運行以從獲取數據。你可以在內做到在表單中獲取數據到目前為止,我們只有和按鈕的組合。現在,在獲取數據時,可以使用向函數發送信息。例如,在成功請求的情況下,用于設置新狀態對象的數據。 原文鏈接: https://www.robinwieruch.de/r... 在本教程中,我想通過state和effect hook來像你展示如何用React Hook...
摘要:難道還不允許設計得對新人更友好了我們先把做成就是找罵啊這怎么怪到我們頭上了事實是,即使在內部,也顯然不是所有程序員都熟悉函數式編程的概念。 1.前言介紹 歷史React在2013年開源,在2015引入函數式組件,不過在日常開發中經常被忽略。ReactJS Core Team 確實大部分成員都曾在推特上公開夸贊過對函數式編程 與 ML 系語言(或其特性)的優點:Sebastian 日常提...
閱讀 1865·2021-09-29 09:35
閱讀 2728·2021-09-22 15:25
閱讀 1981·2021-08-23 09:43
閱讀 2062·2019-08-30 15:54
閱讀 3360·2019-08-30 15:53
閱讀 2396·2019-08-30 13:50
閱讀 2408·2019-08-30 11:24
閱讀 2282·2019-08-29 15:37