我正在编写一个自定义钩子,该钩子可以在ReactJs内置钩子“ UseReducer”之前插入任意数量的中间件。所需的效果是:调度=>调用middleware1 => ...调用Middleare i ... =>调用内置调度。我创建了一个自定义函数'useMiddlewareReducer'来连接中间件和ReactJs useReducer。
函数useMiddlewareReducer中的连接过程是不可变的,因此我认为它只能被调用一次。但是实际上,每次重新发布App组件时,都会调用useMiddlewareReducer函数。有什么办法可以防止这种情况?或者,如果我应用了错误的模式,那么在内置reducer之前插入中间件的正确模式是什么?
// useMiddlewareReducer.js
import { useReducer } from 'react';
export default function(reducer, initState, lazyState, ...middleWares) {
// ===== expected middleware signature ======
// function(state,next){
// return function(action){
// ...
// next(new action);
// }
// }
// get state and built-in dispatch from ReactJs
let [state, dispatch] = useReducer(reducer, initState, lazyState);
if (!middleWares || !middleWares.length)
return [state, dispatch];
// middleWares:the array of middleware
// connect all middlewares and insert them before ReactJs dispatch
while (middleWares.length > 0) {
dispatch = middleWares.pop()(state, dispatch);
}
return [state, dispatch];
}
// App.js
import reducer from 'reducer.js';
import useMiddlewareReducer from 'useMiddlewareReducer.js';
import logMiddleware from 'logMiddware.js';
import serviceMiddleware from 'serviceMiddleware.js';
import {DispatchContext} from 'contexts.js';
export default function App(){
let [state,dispatch]=useMiddlewareReducer(reducer,{},undefined,logMiddleware,serviceMiddleware);
return (
<DispatchContext.Provider value={dispatch}>
...
</DispatchContext.Provider>
);
}
在上述代码中,状态更改将导致App组件重新呈现,然后将调用useMiddlewareReducer函数,即,中间件的组装过程发生了许多次。这是无效的。这导致了另一个问题-调度对象将始终是一个新对象,它可能导致DispatchContext的所有使用者无意中进行重新渲染。