如何基于useReducer控制自定义钩子的运行时间

时间:2019-05-20 04:30:00

标签: javascript reactjs hook dispatch

我正在编写一个自定义钩子,该钩子可以在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的所有使用者无意中进行重新渲染。

0 个答案:

没有答案