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