摘要:高階組件以下的所有子組件都可以直接從中獲取數(shù)據(jù)。所以,修改數(shù)據(jù)的函數(shù)出現(xiàn)了即所有的數(shù)據(jù)都必須通過(guò)調(diào)用修改。
redux 只是一個(gè)狀態(tài)管理 簡(jiǎn)述
本篇文章主要說(shuō)明redux的基本原理以及如何使用
閱讀前需了解(本文中僅作簡(jiǎn)單描述,詳細(xì)了解請(qǐng)自行Google)
純函數(shù)
符合以下兩點(diǎn)性質(zhì)的函數(shù)即為純函數(shù)
函數(shù)執(zhí)行不改變外部變量
函數(shù)的輸出結(jié)果僅依賴(lài)于輸入?yún)?shù)
高階組件
即一個(gè)函數(shù),接收一個(gè)組件作為參數(shù),輸出一個(gè)新組件
觀(guān)察者模式
即發(fā)布訂閱模式,可以理解為給一個(gè)事件綁定多個(gè)函數(shù),事件觸發(fā)時(shí)多個(gè)綁定函數(shù)全部執(zhí)行
react基礎(chǔ)
react官方中文文檔
wepy基礎(chǔ)(有vue基礎(chǔ)也可以)
wepy官方文檔
redux react中的context屬性簡(jiǎn)單的說(shuō),context就是一個(gè)全局變量,它可以被一個(gè)高階組件及該高階組件的所有子組件,孫組建等等共享
舉個(gè)例子,下圖是一個(gè)react頁(yè)面react頁(yè)面樹(shù)形結(jié)構(gòu)
正常的狀態(tài)提升及數(shù)據(jù)下放
使用context的樹(shù)形結(jié)構(gòu)
由上面三圖可以看出,本應(yīng)一層一層傳遞的數(shù)據(jù),在使用context后,變得方便了。
高階組件以下的所有子組件都可以直接從context中獲取數(shù)據(jù)。
這看似方便的方法,實(shí)際上引發(fā)了一個(gè)老生常談的問(wèn)題,即全局變量控制問(wèn)題
context 里面的數(shù)據(jù)能被隨意接觸就能被隨意修改,每個(gè)組件都能夠改 context 里面的內(nèi)容會(huì)導(dǎo)致程序的運(yùn)行不可預(yù)料
同時(shí)context的出現(xiàn)也打破了組件和組件之間通過(guò) props 傳遞數(shù)據(jù)的規(guī)范,極大地增強(qiáng)了組件之間的耦合性。
試想,若是所有組件都可以通過(guò)xxx="xxx"來(lái)修改狀態(tài),我們獲取并控制當(dāng)前狀態(tài)的難度是否變大?
在大型復(fù)雜項(xiàng)目中,我們可能都無(wú)法確定某數(shù)據(jù)是如何變成當(dāng)前值的
為了避免這種情況出現(xiàn),redux就出現(xiàn)了
為了解決模塊(組件)之間需要共享數(shù)據(jù)和數(shù)據(jù)可能被任意修改導(dǎo)致不可預(yù)料的結(jié)果時(shí)間的矛盾,
redux團(tuán)隊(duì)想出了一個(gè)辦法,即把事情搞復(fù)雜一些,提高數(shù)據(jù)修改的門(mén)檻:模塊(組件)之間可以共享數(shù)據(jù),也可以改數(shù)據(jù)。但是我們約定,這個(gè)數(shù)據(jù)并不能直接改,你只能執(zhí)行某些我允許的某些修改,而且你修改的必須大張旗鼓地告訴我。
function dispatch (action) { switch (action.type) { case "UPDATE_TITLE_TEXT": appState.title.text = action.text break case "UPDATE_TITLE_COLOR": appState.title.color = action.color break default: break } }
即所有的數(shù)據(jù)都必須通過(guò)調(diào)用dispatch修改。
dispatch({ type: "UPDATE_TITLE_TEXT", text: "hello world" }) // 修改標(biāo)題文本 dispatch({ type: "UPDATE_TITLE_COLOR", color: "blue" }) // 修改標(biāo)題顏色如圖所示
引入redux前,各組件直接修改數(shù)據(jù)
現(xiàn)在,必須通過(guò)dispatch修改數(shù)據(jù)
抽離store并監(jiān)控?cái)?shù)據(jù)變化我們把它們集中到一個(gè)地方,給這個(gè)地方起個(gè)名字叫做 store,然后構(gòu)建一個(gè)函數(shù) createStore,用來(lái)專(zhuān)門(mén)生產(chǎn)這種 state 和 dispatch 的集合,這樣別的 App 也可以用這種模式了:
/** *@param *state 初始狀態(tài) *stateChanger 一個(gè)修改state的函數(shù) */ function createStore (state, stateChanger) { const getState = () => state const dispatch = (action) => stateChanger(state, action) return { getState, dispatch } }
本例中頁(yè)面通過(guò)renderApp等函數(shù)刷新,為了避免dispatch后頁(yè)面數(shù)據(jù)不變化(render函數(shù)不執(zhí)行)
我們必須引入觀(guān)察者模式,使dispatch后,app自動(dòng)執(zhí)行render函數(shù)
function createStore (state, stateChanger) { const listeners = [] const subscribe = (listener) => listeners.push(listener) const getState = () => state const dispatch = (action) => { stateChanger(state, action) listeners.forEach((listener) => listener()) } return { getState, dispatch, subscribe } } function renderApp (appState) { renderTitle(appState.title) renderContent(appState.content) } function renderTitle (title) { const titleDOM = document.getElementById("title") titleDOM.innerHTML = title.text titleDOM.style.color = title.color } function renderContent (content) { const contentDOM = document.getElementById("content") contentDOM.innerHTML = content.text contentDOM.style.color = content.color } let appState = { title: { text: "React.js 小書(shū)", color: "red", }, content: { text: "React.js 小書(shū)內(nèi)容", color: "blue" } } function stateChanger (state, action) { switch (action.type) { case "UPDATE_TITLE_TEXT": state.title.text = action.text break case "UPDATE_TITLE_COLOR": state.title.color = action.color break default: break } } const store = createStore(appState, stateChanger) store.subscribe(() => renderApp(store.getState())) // 監(jiān)聽(tīng)數(shù)據(jù)變化 renderApp(store.getState()) // 首次渲染頁(yè)面 store.dispatch({ type: "UPDATE_TITLE_TEXT", text: "《React.js 小書(shū)》" }) // 修改標(biāo)題文本 store.dispatch({ type: "UPDATE_TITLE_COLOR", color: "blue" }) // 修改標(biāo)題顏色
至此,我們已經(jīng)大概構(gòu)建了一個(gè)redux的骨架,接下來(lái)我們將完善它
嚴(yán)重的性能問(wèn)題不知道讀者有沒(méi)有發(fā)現(xiàn),當(dāng)我們通過(guò)dispatch修改標(biāo)題的文字時(shí),整個(gè)App就會(huì)刷新一次,
當(dāng)我們修改文本的顏色時(shí),整個(gè)App也會(huì)刷新一次,這樣就頻繁的全部刷新就造成了極大的性能問(wèn)題
那么,能否修改title,僅刷新title;修改content,也僅刷新content呢?
我們使render函數(shù)接收2個(gè)參數(shù)(newState, oldState = {})并且在刷新前進(jìn)行比較
function renderApp (newAppState, oldAppState = {}) { // 防止 oldAppState 沒(méi)有傳入,所以加了默認(rèn)參數(shù) oldAppState = {} if (newAppState === oldAppState) return // 數(shù)據(jù)沒(méi)有變化就不渲染了 console.log("render app...") renderTitle(newAppState.title, oldAppState.title) renderContent(newAppState.content, oldAppState.content) } function renderTitle (newTitle, oldTitle = {}) { if (newTitle === oldTitle) return // 數(shù)據(jù)沒(méi)有變化就不渲染了 console.log("render title...") const titleDOM = document.getElementById("title") titleDOM.innerHTML = newTitle.text titleDOM.style.color = newTitle.color } function renderContent (newContent, oldContent = {}) { if (newContent === oldContent) return // 數(shù)據(jù)沒(méi)有變化就不渲染了 console.log("render content...") const contentDOM = document.getElementById("content") contentDOM.innerHTML = newContent.text contentDOM.style.color = newContent.color }
這樣就可以提高性能了吧,每次只刷新需要刷新部分啦~~
才怪!
我們確實(shí)修改了對(duì)象內(nèi)的屬性值,但是newState和oldState所指的不還是一個(gè)對(duì)象嗎?
所以為了進(jìn)行判斷,我們還要修改前面的stateChanger函數(shù)
function stateChanger (state, action) { switch (action.type) { case "UPDATE_TITLE_TEXT": return { // 構(gòu)建新的對(duì)象并且返回 ...state, title: { ...state.title, text: action.text } } case "UPDATE_TITLE_COLOR": return { // 構(gòu)建新的對(duì)象并且返回 ...state, title: { ...state.title, color: action.color } } default: return state // 沒(méi)有修改,返回原來(lái)的對(duì)象 } }
現(xiàn)在我們才真正提高了性能
reduer為了讓程序的結(jié)構(gòu)更加清晰,我們把原始state放入stateChanger中,并把stateChanger改名為reducer
為什么叫redcer? 別問(wèn)為什么,沒(méi)有理由!
function reducer (state, action) { if (!state) { return { title: { text: "hello world", color: "red", }, content: { text: "hello world content", color: "blue" } } } switch (action.type) { case "UPDATE_TITLE_TEXT": return { ...state, title: { ...state.title, text: action.text } } case "UPDATE_TITLE_COLOR": return { ...state, title: { ...state.title, color: action.color } } default: return state } }總結(jié)
現(xiàn)在的代碼和react,wepy關(guān)系都不大,在下一篇文章中,我會(huì)講述如何具體地在react中使用redux
感謝 @胡子大哈 老師的《react小書(shū)》,本章有很多代碼都是摘自該書(shū)
react小書(shū)
全部代碼make-redux
本文如果有錯(cuò),歡迎指出
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100205.html
摘要:和的結(jié)合簡(jiǎn)述相信很多前端開(kāi)發(fā)者都聽(tīng)說(shuō)或使用過(guò),我曾寫(xiě)過(guò)一篇關(guān)于快速理解的文章,雖說(shuō)是快速理解,但實(shí)際上更應(yīng)該叫做復(fù)習(xí)吧。它通過(guò)高階函數(shù),純函數(shù)使我們?cè)诰帉?xiě)組件時(shí)完全不用接觸相關(guān)內(nèi)容,只通過(guò)將組件和數(shù)據(jù)連接起來(lái)即可。 react-redux react和redux的結(jié)合 簡(jiǎn)述 相信很多前端開(kāi)發(fā)者都聽(tīng)說(shuō)或使用過(guò)react-redux,我曾寫(xiě)過(guò)一篇關(guān)于快速理解redux的文章,雖說(shuō)是快...
摘要:深入簡(jiǎn)述在快速理解中,我簡(jiǎn)單的介紹了的基礎(chǔ)內(nèi)容,本篇文章中,我們將再度深入。二修改我曾在快速理解中提起,為了解決模塊組件之間需要共享數(shù)據(jù)和數(shù)據(jù)可能被任意修改導(dǎo)致不可預(yù)料的結(jié)果的矛盾,團(tuán)隊(duì)創(chuàng)建了。 深入Redux 簡(jiǎn)述 在快速理解redux中,我簡(jiǎn)單的介紹了redux的基礎(chǔ)內(nèi)容,本篇文章中,我們將再度深入redux。 redux解決的問(wèn)題 數(shù)據(jù)和函數(shù)的層層傳遞 多個(gè)組件同時(shí)修改某全局變...
摘要:協(xié)調(diào)狀態(tài)的這三個(gè)方面是前端開(kāi)發(fā)的重要組成部分,對(duì)這項(xiàng)任務(wù)有不同程度的支持。這使得保持高度統(tǒng)一。的真正威力到目前為止,看上去只是的輔助工具。在的術(shù)語(yǔ)中這稱(chēng)之為派發(fā)動(dòng)作。撤銷(xiāo)重做流行的撤銷(xiāo)重做功能需要系統(tǒng)級(jí)規(guī)劃。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 你知道 Redux 真正的作用遠(yuǎn)不止?fàn)顟B(tài)管理嗎? 你是否想要了解 Redux 的工作原理? 讓我們深入研究 ...
摘要:相關(guān)配置請(qǐng)參考中文文檔。關(guān)于的更多使用方法及理解需要詳細(xì)具體講解,涉及篇幅較大,本文暫不涉及,有興趣可以看文檔中文文檔,我會(huì)整理后再單獨(dú)章節(jié)分享接下來(lái)我們將編寫(xiě)路由組件這與有一些差別,原來(lái)的方法已經(jīng)不再使用,在中或組件從中引入。 ??????相信很多剛?cè)肟覴eact的小伙伴們有一個(gè)同樣的疑惑,由于React相關(guān)庫(kù)不斷的再進(jìn)行版本迭代,網(wǎng)上很多以前的技術(shù)分享變得不再適用。比如react-...
摘要:基礎(chǔ)瀏覽器渲染機(jī)制水平居中垂直居中數(shù)組的幾個(gè)方法對(duì)比閉包作用域原型與原型鏈繼承的介紹事件冒泡與捕獲只支持事件冒泡不支持事件捕獲,如何在上實(shí)現(xiàn)事件捕獲運(yùn)行機(jī)制相關(guān)介紹你經(jīng)常用到的的新特性方法網(wǎng)絡(luò)請(qǐng)求響應(yīng)分別有哪些頭字段,有什么作用緩存相關(guān)響 基礎(chǔ) 瀏覽器渲染機(jī)制 CSS 水平居中、垂直居中BFC 數(shù)組的幾個(gè)方法對(duì)比閉包作用域this原型與原型鏈、繼承的介紹事件冒泡與捕獲(IE6只支持事件...
閱讀 2805·2021-10-11 11:08
閱讀 1525·2021-09-30 09:48
閱讀 1083·2021-09-22 15:29
閱讀 1076·2019-08-30 15:54
閱讀 1006·2019-08-29 15:19
閱讀 563·2019-08-29 13:12
閱讀 3196·2019-08-26 13:53
閱讀 998·2019-08-26 13:28