Redux中間部品の原理について詳しく説明する.
7177 ワード
中間部品を解析するために、いくつかの中間部品がどのように使われていますか?運行の原理は何ですか?
1、ミドルウェアはどんな形ですか?
1.2 thunk中間部品
3、中間部品の運行原理
中間部品の実行原理はkoa中間部品の実行原理と似ていますが、玉ねぎ型ではなく、半玉ねぎです.reduxは一方通行ですので、歩いて行けば大丈夫です.中間部品を適用して、一つのaction操作をトリガすると、action操作は先に中間部品を経由して、最終的にdispatchを形成します.二つの中間部品を例にとって、一つのaction動作をトリガする場合、コードの実行ロジックを説明します.thunk:オブジェクトではなく、dispatchの関数を許可します.例外的にログを印刷します.
3.1中間部品の内部ロジック
3.2 actionをトリガする場合、論理を実行する
非同期印刷ログをトリガする機能を設定します.アプリケーション中間 action関数 このlogNextを実行すると、関数を返します.関数のパラメータはdispatchとget Stateの2つです.実行プロセス
付録
copsoe
1、ミドルウェアはどんな形ですか?
1.2 thunk中間部品
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
// ,
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
// ,
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
1.2 promiseミドルウェアimport isPromise from 'is-promise';
import { isFSA } from 'flux-standard-action';
export default function promiseMiddleware({ dispatch }) {
return next => action => {
if (!isFSA(action)) {
return isPromise(action) ? action.then(dispatch) : next(action);
}
return isPromise(action.payload)
? action.payload
.then(result => dispatch({ ...action, payload: result }))
.catch(error => {
dispatch({ ...action, payload: error, error: true });
return Promise.reject(error);
})
: next(action);
};
}
1.3 loggerミドルウェアconst defaultLogger = ({ dispatch, getState } = {}) => {
if (typeof dispatch === 'function' || typeof getState === 'function') {
return createLogger()({ dispatch, getState });
}
};
function createLogger(options = {}) {
const loggerOptions = Object.assign({}, defaults, options);
const {
logger,
stateTransformer,
errorTransformer,
predicate,
logErrors,
diffPredicate,
} = loggerOptions;
if (typeof logger === 'undefined') {
return () => next => action => next(action);
}
import { logger } from 'redux-logger'
const store = createStore(
reducer,
applyMiddleware(logger))
import { createLogger } from 'redux-logger'
const logger = createLogger({
// ...options
});
const store = createStore(
reducer,
applyMiddleware(logger));
return () => next => action => next(action);
}
const logBuffer = [];
return ({ getState }) => next => (action) => {
if (typeof predicate === 'function' && !predicate(getState, action)) {
return next(action);
}
const logEntry = {};
logBuffer.push(logEntry);
logEntry.started = timer.now();
logEntry.startedTime = new Date();
logEntry.prevState = stateTransformer(getState());
logEntry.action = action;
let returnedValue;
if (logErrors) {
try {
returnedValue = next(action);
} catch (e) {
logEntry.error = errorTransformer(e);
}
} else {
returnedValue = next(action);
}
logEntry.took = timer.now() - logEntry.started;
logEntry.nextState = stateTransformer(getState());
const diff = loggerOptions.diff && typeof diffPredicate === 'function'
? diffPredicate(getState, action)
: loggerOptions.diff;
printBuffer(logBuffer, Object.assign({}, loggerOptions, { diff }));
logBuffer.length = 0;
if (logEntry.error) throw logEntry.error;
return returnedValue;
};
}
export { defaults, createLogger, defaultLogger as logger };
export default defaultLogger;
2、ミドルウェアの使い方const store = createStore(rootReducer, initialState,
applyMiddleware(thunk),
... ...
);
簡単に言えば、createStoreはこのようなことをしました.目的はあなたが伝えてきたreducerと初期状態initial Stateから初期化storeを生成し、列操作のインターフェースを提供しました.dispachなどはどうしますか?Redux-creat Store/compose本文を参照して、中間部品の実行過程と原理を重点的に説明します.3、中間部品の運行原理
中間部品の実行原理はkoa中間部品の実行原理と似ていますが、玉ねぎ型ではなく、半玉ねぎです.reduxは一方通行ですので、歩いて行けば大丈夫です.中間部品を適用して、一つのaction操作をトリガすると、action操作は先に中間部品を経由して、最終的にdispatchを形成します.二つの中間部品を例にとって、一つのaction動作をトリガする場合、コードの実行ロジックを説明します.thunk:オブジェクトではなく、dispatchの関数を許可します.例外的にログを印刷します.
3.1中間部品の内部ロジック
const store = createStore(reducer, preloadedState, enchancer);
// , action;
// creatStore
// enchancer , applyMiddleware
function applyMiddleware(...middlewares) {
return createStore => (...args) => {
// store , , , store
const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
// getState、dispatch
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
// ,
// next => {}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
// ,
// action => {}
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
//
// a b
// a(b(store.dispatch))
return enchancer(createStore)(reducer, preloadedState);
// thunk
({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
return next(action);
};
上記の操作を経て、中間包装後のstoreはどうなりますか?仮に中間部品がa b cで中間部品がない場合はこのようになります.store = {
dispatch,
... ...,
subscribe,
getState
}
中間包装を経て、storeが変わりました.store = {
dispatch: a(b((store.dispatch))),
... ...,
subscribe,
getState
}
まとめとは、中間部品ごとにオリジナルのstoreのdispatchを配付し、中間部品の関数をネストして実行することです.3.2 actionをトリガする場合、論理を実行する
非同期印刷ログをトリガする機能を設定します.
const store = createStore(rootReducer, initialState,
applyMiddleware(thunk)
);
上の操作を経て、今のstoreは{
dispatch: action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
},
... ...,
subscribe,
getState
}
const logNext = () => (dispatch, getState) => {
setTimeout(
dispatch({
type: 'LOG',
payload: {
content: ' '
}})
,5000);
}
---->
store.dispatch(logNext()) // ,
---->
(dispatch, getState) => {
setTimeout(
dispatch({
type: 'LOG',
payload: {
content: ' '
}})
,5000);
}
---->
redux-thunkはパッケージ関数であり、store.dispatchの関数が複数ある場合、実行過程はどのようになりますか?ポイントはnext(action)で、nextは何ですか?nextは中間の仕事ごとです.next => action => {}
分かりましたか付録
copsoe
// compose ,
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)))
}