Redux分析
6386 ワード
Reduxは何ですか
ReduxはJavascript状態容器であり、予測可能な状態管理を提供する.
Reduxの機能と役割状態を一つのstateに統一し、storeによってこのstate を管理する. storeはreducerのshopによって を作成します. storeはdispatchのactionを通して、reducerによって統一的に を更新します.毎回dispatchを使用すると、subscribeによってstoreの変化を監視することができます.
適用シーン 複数ページの共有が必要なデータ 地方のデータが変わりました.他のところのデータも同期して を変更します.
シーンは適用されませんデータは、単一のコンポーネントまたは単一のスコープだけで を使用する.データの変更後、再レンダリングする必要はありません.
Reduxとグローバルオブジェクトの違いは何ですか? Reduxのデータはstoreに保存されています.dispatchの一つのactionによってしか修正できません.デバッグに便利です.どんな変更も一回の変更記録があります. グローバルオブジェクトの値は直接的に修正できます.修正後は記録がなく、調整が不便です.不適切な使用はグローバル変数汚染を引き起こしやすいです.
原理解析を実現する
Reduxのワークフローは: 作成store、すなわち、createStore() は、複数のreducerを一つのreducer、すなわち、commbindReducers() に統合する.中間部品、すなわちappyMiddlewareを適用する() ソースディレクトリには、compose、bindActioCreatorsの2つのファイルが含まれています.この2つのファイルは主にいくつかの方法を提供するためのものです.
それぞれのソースコードを解析します.
createStore
キーコードは以下の通りです.
get State
compse
composeの役割は、複数の方法を一つの包装にすることです.
commbineReducersを知るには、先にreducerが何かを知るべきですか?その役割は何ですか?
reducerは、reduxがdispatchのactionを通じて、storeの純粋な関数方法を更新するために用いられる.更新storeのreducerは一つしかないかもしれませんが、業務量が大きく、機能モジュールがたくさん区分されています.一つのreducerだけを使ってデータを更新するとreducerが長くなります.後期にbugに遭遇した場合は、検査が困難になりますので、reducerをstore作成時の構造に従って複数のreducerに分割することができます.最後にcommbineReducersを通じて一つのreducerに合併します.
中間ボタンは何ですか?まずコアコードを見てください.
どのようにReactフレームと組み合わせて使うか?
react-reduxフレームを使って、私達の実現を助けてくれます.
具体的な実現を理解して、react-reduxソースコードをクリックして解析します.
Q&A dispatchは同期ですか?それとも非同期ですか?dispatchは同期してstoreを更新します. はなぜreactレンダリングを使用する時に非同期なのですか?reduxがreactの使用を結合する時、実はconnectという高次のコンポーネントを使ってデータの更新を実現していますので、storeのデータが変化したことを傍受した後、reactのsetsState方法を呼び出してページを再レンダリングします.setsStateは非同期です.だからdispachは非同期ではなく、setsStateは非同期です. reduxのsubscribeはどうやって実現されますか? 参照リンクhttps://www.redux.org.cn/ https://juejin.im/post/5b9617835188255c781c9e2f
ReduxはJavascript状態容器であり、予測可能な状態管理を提供する.
Reduxの機能と役割
適用シーン
シーンは適用されません
Reduxとグローバルオブジェクトの違いは何ですか?
原理解析を実現する
Reduxのワークフローは:
それぞれのソースコードを解析します.
createStore
キーコードは以下の通りです.
export default function createStore(reducer, preloadedState, enhancer) {
if (enhancer ) {
return enhancer(createStore)(reducer, preloadedState)
}
let currentReducer = reducer
let currentState = preloadedState
let currentListeners = []
let nextListeners = currentListeners
let isDispatching = false
// state
function getState() {
return currentState
}
// , dispatch
function subscribe(listener) {
let isSubscribed = true
// currentListeners
ensureCanMutateNextListeners()
// push
nextListeners.push(listener)
return function unsubscribe() {
isSubscribed = false
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
}
function dispatch(action) {
try {
isDispatching = true
// state, action, state
currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
}
const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
//
listener()
}
return action
}
return {
dispatch,
subscribe,
getState,
}
}
上記からわかるように、createStore方法でstoreを作成しました.作成後は直接storeを返しませんでした.操作storeに関するいくつかの方法を返しました.主にgetsStore、subscribe、dispachがあります.get State
function getState() {
return currentState;
}
createStoreによって作成されたstoreは、直接にその中のデータにアクセスするにはget Stateによってしか返されないデータは、currentStateオブジェクトの参照であり、直接に修正することができますが、reudxはこのようにしない方がいいと提案しています.compse
composeの役割は、複数の方法を一つの包装にすることです.
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
compose(funcA, funcB, funcC, funD)
出力結果は:funcA(funcB(func(funcD())))
commbineReducerscommbineReducersを知るには、先にreducerが何かを知るべきですか?その役割は何ですか?
reducerは、reduxがdispatchのactionを通じて、storeの純粋な関数方法を更新するために用いられる.更新storeのreducerは一つしかないかもしれませんが、業務量が大きく、機能モジュールがたくさん区分されています.一つのreducerだけを使ってデータを更新するとreducerが長くなります.後期にbugに遭遇した場合は、検査が困難になりますので、reducerをstore作成時の構造に従って複数のreducerに分割することができます.最後にcommbineReducersを通じて一つのreducerに合併します.
export default function combineReducers(reducers) {
// reducer key
const reducerKeys = Object.keys(reducers)
const finalReducers = {}
for (let i = 0; i < reducerKeys.length; i++) {
const key = reducerKeys[i]
// reducer , reducer
if (typeof reducers[key] === 'function') {
finalReducers[key] = reducers[key]
}
}
// reducer key
const finalReducerKeys = Object.keys(finalReducers)
let shapeAssertionError
try {
// reducer , reducer ,
assertReducerShape(finalReducers)
} catch (e) {
shapeAssertionError = e
}
return function combination(state = {}, action) {
if (shapeAssertionError) {
throw shapeAssertionError
}
let hasChanged = false
const nextState = {}
for (let i = 0; i < finalReducerKeys.length; i++) {
// reducer key
const key = finalReducerKeys[i]
// reducer
const reducer = finalReducers[key]
// key state
const previousStateForKey = state[key]
// state , action, reducer state
const nextStateForKey = reducer(previousStateForKey, action)
// state
nextState[key] = nextStateForKey
// ,
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
// , state, , state
return hasChanged ? nextState : state
}
}
appyMiddleware中間ボタンは何ですか?まずコアコードを見てください.
export default function applyMiddleware(...middlewares) {
// applyMiddleware , store
return createStore => (...args) => {
const store = createStore(...args)
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
// , store dispatch ,
const chain = middlewares.map(middleware => middleware(middlewareAPI))
// compose
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
上記のステップを経て、中間キーは通常action関数に戻ります.dispatchを書き換えます.今度はdispatchを呼び出します.実は書き換えたdispatchを呼び出します.このようにdispatchとreducerの間に、カスタムで実行できる方法を追加しました.dispatchとreducerの間で、データを要求するなどの非同期操作ができます.ログなどの機能を印刷します.これらの機能を全部実行した後に、dispatchの本当の純粋なactionを直して、reducerを修正します.このように既存のコードを修正しない上に、中間挿入操作の機能を達成しました.どのようにReactフレームと組み合わせて使うか?
react-reduxフレームを使って、私達の実現を助けてくれます.
具体的な実現を理解して、react-reduxソースコードをクリックして解析します.
Q&A