react 判断地址是否有效_继续,react-redux原理解析
本文原文鏈接
在之前的一篇文章中已講過redux 原理解析,我將redux返回的store對象掛載在window中,不是太懂的同學可以看看之前的redux 原理解析。
const reducer = combineReducers({home: homeNumber,number: addNumber }) const store = createStore(reducer) window.$reduxStore = store// 使用 window.$reduxStore.dispatch(action); let { state } = window.$reduxStore.getState()但在平時的開發(fā)中,一般是將redux+react-redux+react配合使用,那么,下面就一起來看看react-redux中的常見方法,它具體做了什么。【下面是以最新版本react-redux@7.1.3庫解析】(下面的源碼部分省略)
#Provider函數(shù)
react-redux提供了<Provider />組件用來掛載redux返回的store對象,同時將整個應用作為Provider的子組件。
ReactDOM.render( <Provider store={store}> <App /> </Provider>, rootElement )下面看看<Provider />組件做了什么:
function Provider({ store, context, children }) {// 依賴項store變化觸發(fā),返回store和subscriptionconst contextValue = useMemo(() => {// 訂閱監(jiān)聽Subscription函數(shù),下面會專門說到const subscription = new Subscription(store)subscription.onStateChange = subscription.notifyNestedSubsreturn {store,subscription}}, [store])//...// ReactReduxContext = React.createContext(null)const Context = context || ReactReduxContextreturn <Context.Provider value={contextValue}>{children}</Context.Provider> } // 源碼地址:https://github.com/reduxjs/react-redux/blob/master/src/components/Provider.js#L6Provider接收三個參數(shù),store參數(shù)接收store對象,context參數(shù)接收上下文對象,children參數(shù)接收ReactElement元素; 在原應用組件上包裹一層,使原來整個應用成為Provider的子組件,Context.Provider API:只有當 Provider 的 value 值發(fā)生變化時,它內(nèi)部的所有消費組件都會重新渲染。
將contextValue掛載在Provider上,contextValue包含store對象和訂閱發(fā)布subscription對象,以備connect組件使用獲取。Subscription主要負責connect、Provider組件的更新,屬于核心內(nèi)容,這些將在下面講到。
#connect函數(shù)
connect的常見使用示例:
return connect(mapStateToProps, mapDispatchToProps)(Component)connect函數(shù)就是一個高階組件,將以上的參數(shù)傳入函數(shù),返回一個新的組件,主要就是將state和dispatch等屬性掛載Component的props上。
import hoistStatics from 'hoist-non-react-statics' import { ReactReduxContext } from './Context';// 核心函數(shù) return組件 function ConnectFunction (props) {// ...// 判斷props 是否存在store & getState & dispatch,一般都為falsevar didStoreComeFromProps = Boolean(props.store) && Boolean(props.store.getState) && Boolean(props.store.dispatch);// 獲取Provider組件掛載的contextValuevar ContextToUse = useMemo(function () {return propsContext &&propsContext.Consumer &&isContextConsumer(<propsContext.Consumer />)? propsContext: Context})// contextValue = { store, subscription }var contextValue = useContext(ContextToUse)// ...// 依賴返回 contextValuevar overriddenContextValue = useMemo(function () {if (didStoreComeFromProps) {return contextValue}return {...contextValue,subscription}}, [didStoreComeFromProps, contextValue, subscription]);// ...// actualChildProps == props,上掛載了```state```和```dispatch```等屬性const renderedWrappedComponent = useMemo(() => <WrappedComponent {...actualChildProps} ref={forwardedRef} />,[forwardedRef, WrappedComponent, actualChildProps])// 返回渲染ReactElementvar renderedChild = useMemo(function () {// 判斷是否存在mapStateToProps函數(shù)if (shouldHandleStateChanges) {return (<ContextToUse.Provider value={overriddenContextValue}>{renderedWrappedComponent}</ContextToUse.Provider>)}// renderedWrappedComponent 渲染容器組件return renderedWrappedComponent}, [ContextToUse, renderedWrappedComponent, overriddenContextValue]);return renderedChild; } // ... // 與Object.assign類似操作 return hoistStatics(ConnectFunction, WrappedComponent)hoistStatics函數(shù)的作用就是類似于Object.assign,可以這樣理解hoistStatics(targetComponent, sourceComponent),hoist-non-react-statics庫。上面代碼中ConnectFunction是核心函數(shù),雖然中間部分代碼省略,不過留下的都是精華。
在ConnectFunction函數(shù)中,通過hooks useContext獲取Provider組件的contextValue對象;renderedWrappedComponent將actualChildProps作為props傳入,actualChildProps是已經(jīng)處理過的props屬性,上面已經(jīng)掛載了dispatch函數(shù)和state狀態(tài)等屬性;而renderedChild組件,其實connect函數(shù)最后返回的實際內(nèi)容。(中間部分代碼省略了源碼鏈接跳轉(zhuǎn))
以上就是Provice組件和connect組件初次調(diào)用時,所經(jīng)過的實際代碼,當然在其中有一些刪減,不過基本都有說到。
當dispatch被調(diào)用時,會發(fā)生什么呢?上面部分完全沒有說到,下面我們就來看看當dispatch(action)調(diào)用后,react-redux內(nèi)部,是如何更新connect組件。
#connect如何更新?
當在React應用中調(diào)用dispatch函數(shù)時,redux中實際調(diào)用的就是reducer函數(shù),同時返回新的state。那么redux-react中的connect組件如何更新呢,下面我們來一起看看更新的流程:
dispatch(action)下面內(nèi)容不是精讀代碼,只是聊一下基本的流程。
#初始化
當Provider組件被調(diào)用注冊時,訂閱更新Subscription函數(shù)被注冊:
const subscription = new Subscription(store)在redux-react中,訂閱發(fā)布函數(shù)Subscription是其中的核心函數(shù)(訂閱發(fā)布模式是其核心),它有效的保證connect組件的更新渲染。store作為參數(shù)傳入到Subscription構(gòu)造函數(shù)內(nèi)部,作用就是Subscription內(nèi)部使用。
#訂閱
return connect(mapStateToProps, mapDispatchToProps)(Component)// react-redux中,checkForUpdates函數(shù),負責更新connect組件 subscription.onStateChange = checkForUpdates// redux保存觸發(fā) 通知函數(shù) store.subscribe(subscription.notifyNestedSubs);// react-redux保存 更新函數(shù) subscription.listeners.subscribe(subscription.onStateChange)在connect組件被使用時,react-redux中的subscription對象,會將connect組件的checkForUpdates更新函數(shù)作為參數(shù),傳入保存在subscription的訂閱數(shù)組next中;同時,redux也會發(fā)生相同的操作【在react-redux中也有使用到redux中方法】。(代碼為簡化版)
// redux中 subscribe函數(shù) let nextListeners = [] subscribe(listener) {// ... nextListeners.push(listener) } // react-redux中 subscribe函數(shù) let next = [] subscribe(listener) {// ... next.push(listener) }checkForUpdates函數(shù)負責connect組件的內(nèi)部的狀態(tài)更新。
notifyNestedSubs函數(shù)是作用是觸發(fā)react-redux中的subscription對象的更新函數(shù),而它被保存在nextListeners數(shù)組中,是為了當redux的dispatch函數(shù)被觸發(fā)時,調(diào)用notifyNestedSubs通知函數(shù),進而觸發(fā)react-redux的connect組件的checkForUpdates更新函數(shù)。
react-redux:checkForUpdates 函數(shù)源碼
react-redux:Subscription 函數(shù)源碼
#發(fā)布(更新)
dispatch(action)發(fā)起觸發(fā)操作后,當然是觸發(fā)store中dispatch函數(shù)了,修改store中state的值,更新遍歷redux的nextListeners訂閱數(shù)組,觸發(fā)通知函數(shù)notifyNestedSubs調(diào)用;同時,這會導致react-redux中的next數(shù)組,被觸發(fā)遍歷調(diào)用。兩個庫基本都是下面的代碼
let next = listeners;? for (let i = 0; i < listeners.length; i++) {listeners[i]() }以上細節(jié)可能有所省略,但基本就是先訂閱,將更新函數(shù)保存進入訂閱數(shù)組,然后當dispatch函數(shù)被調(diào)用時,遍歷調(diào)用訂閱數(shù)組,完成connect組件的更新。
在最新的react-redxu庫中 ,有大量的React Hooks出現(xiàn),中間我木有過多的說明,有興趣可以自行研究。(高階組件、React Hooks、訂閱發(fā)布模式)
ps: 微信公眾號:Yopai,有興趣的可以關注,每周不定期更新。不斷分享,不斷進步
與50位技術專家面對面20年技術見證,附贈技術全景圖總結(jié)
以上是生活随笔為你收集整理的react 判断地址是否有效_继续,react-redux原理解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: yaml数组解析_yaml格式详解
- 下一篇: jsp 知乎_JSP