Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React Hooks-usereducewithcallback_Javascript_Reactjs_React Native_React Hooks - Fatal编程技术网

Javascript React Hooks-usereducewithcallback

Javascript React Hooks-usereducewithcallback,javascript,reactjs,react-native,react-hooks,Javascript,Reactjs,React Native,React Hooks,我正在重构我的一个上下文的复杂状态管理,它以前使用了钩子“useStateWithCallback” 我决定使用“useReducer”重构代码,这将使代码更具可读性 目前,我正在这样做: export function ContentsProvider({ children }) { const [contents, setContents] = useStateWithCallback(new Map([])); const addContents = (newContents,

我正在重构我的一个上下文的复杂状态管理,它以前使用了钩子“useStateWithCallback”

我决定使用“useReducer”重构代码,这将使代码更具可读性

目前,我正在这样做:

export function ContentsProvider({ children }) {
  const [contents, setContents] = useStateWithCallback(new Map([]));

  const addContents = (newContents, callback = undefined) => {
    setContents(
      (prevContents) => new Map([...prevContents, ...newContents]),
      callback
    );
  };
  
  ...
现在,在使用此上下文的任何应用程序组件上,我都可以执行以下操作:

contents.addContents([ ... ], () => { ... });
只有当状态发生变化时,才会执行回调

有没有办法通过useReducer实现这种行为?我的意思是,如果我将回调作为参数传递给我的提供者的方法,那么我将无法运行

useEffect(() => { callback?.() } , [contents]);
有什么想法吗

我试过这个:

import { useReducer, useEffect } from 'react'

export const useReducerWithCallback = (
  initialState,
  reducer,
  callback = undefined
) => {
  const [state, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    callback?.(state);
  }, [state, callback]);

  return [state, dispatch];
};

但是它不起作用,因为在我的用例中,回调并不总是相同的,所以我不能用回调声明reducer。

如果我理解您在寻找什么,那么我认为使用React ref和effect的自定义钩子可能实现您所寻求的行为

  • 使用React ref保存对回调的引用
  • 使用
    useffect
    在状态更新时调用回调
  • 返回一个自定义
    dispatch
    函数以设置回调并向reducer函数分派操作
  • 代码

    const useReducerWithCallback=(减速机、初始状态、初始值设定项)=>{
    const callbackRef=React.useRef();
    const[state,dispatch]=React.useReducer(reducer,initialState,initializer);
    React.useffect(()=>{
    callbackRef.current&&callbackRef.current(状态);
    },[州];
    const customDispatch=(操作、回调)=>{
    callbackRef.current=回调;
    派遣(行动);
    };
    返回[状态,customDispatch];
    };
    const reducer=(状态、操作)=>{
    开关(动作类型){
    案例“添加”:
    返回状态+action.payload;
    案例“减法”:
    返回状态-action.payload;
    违约:
    返回状态;
    }
    };
    函数App(){
    const[state,dispatch]=useReducerWithCallback(reducer,0);
    返回(
    状态:{State}
    分派({类型:“添加”,有效负载:1},(状态)=>
    日志(“添加1,状态”,状态)
    )
    }
    >
    +
    分派({type:“SUBTRACT”,有效负载:1},(state)=>
    log(“减去1,状态”,状态)
    )
    }
    >
    -
    );
    }
    const rootElement=document.getElementById(“根”);
    ReactDOM.render(
    ,
    根元素
    );
    
    太棒了!我一直在找这个!从更新callback ref的方法调用dispatch就可以做到这一点!非常感谢
    const useReducerWithCallback = (reducer, initialState, initializer) => {
      const callbackRef = useRef();
      const [state, dispatch] = useReducer(reducer, initialState, initializer);
    
      useEffect(() => {
        callbackRef.current?.(state);
      }, [state]);
    
      const customDispatch = (action, callback) => {
        callbackRef.current = callback;
        dispatch(action);
      };
    
      return [state, customDispatch];
    };