在回调内部传递custum钩子

时间:2019-12-17 12:41:45

标签: reactjs react-hooks

我有一个自定义钩子。我也有一个期望功能的组件。该功能需要调用我的自定义钩子。这就是我想要做的:

<MyComponent onSuccess={(result) => useCustomHook("value", result)} />

我的自定义钩子类似于:

export function useCustomHook(param1, param2)
{
    const dispatch = useDispatch();
    dispatch(actionCreator.someAction(param1, param2));
    dispatch(actionCreator.setSomeValue(true));
}

我收到一条错误消息:

  

无法在回调内部调用反应挂钩

我知道有规则说我应该只在功能组件的顶层调用钩子,那么我到底该如何实现我想要的?

1 个答案:

答案 0 :(得分:0)

我看不到您的自定义钩子在做什么(更重要的是,返回)。但是钩子的实现需要看起来像这样:

function OtherComponent () {
  const callback = useCustomHook("value");

  return (
    <MyComponent onSuccess={(result) => callback(result)} />
  );
}

在您的useCustomHook中,您可以返回一个函数,您可以调用该函数来完成您想要实现的目标。

例如,如果您希望每次值更改时都发出请求,则您的自定义钩子可能如下所示:

function useCustomHook() {
  const [value, setValue] = useState();

  useEffect(() => {
    fetch(`http://my.api/${value}`);
  }, [value]);

  return setValue;
}

现在setValue是从useCustomHook函数返回的,可以在您的组件中使用它来更改自定义钩子中的value状态。

修改

您已经添加了自定义钩子,该钩子实际上看起来与上面的示例非常相似:

export function useCustomHook(key) {
  const dispatch          = useDispatch();
  const [value, setValue] = useState();

  useEffect(() => {
    dispatch(actionCreator.someAction(key, value));
    dispatch(actionCreator.setSomeValue(true));
  }, [key, value, dispatch]);

  return setValue;
}

仅当给定的“依赖项”之一更改时,useEffect钩子才会被调用。在上述情况下,只有在调用返回值且给定值发生更改时才设置的value

如果param1从不更改,则可以将其用作自定义钩子的参数,但如果确实发生变化,则该钩子看起来会有所不同:

export function useCustomHook() {
  const dispatch          = useDispatch();
  const [key, setKey]     = useState();
  const [value, setValue] = useState();

  useEffect(() => {
    dispatch(actionCreator.someAction(key, value));
    dispatch(actionCreator.setSomeValue(true));
  }, [key, value, dispatch]);

  return (key, value) => {
    setKey(key);
    setValue(value);
  };
}

在组件中,您可以像这样使用它:

function OtherComponent () {
  const callback = useCustomHook();

  return (
    <MyComponent onSuccess={(result) => callback('value', result)} />
  );
}

第二次修改

如评论中所述,在这种情况下,根本不需要自定义钩子。您可以只使用常规函数并省略use前缀:

function OtherComponent () {
  const dispatch = useDispatch();
  const callback = (param1, param2) => {
    dispatch(actionCreator.someAction(param1, param2));
    dispatch(actionCreator.setSomeValue(true));
  };

  return (
    <MyComponent onSuccess={(result) => callback('value', result)} />
  );
}

如果您仍然想创建一个自定义钩子,并且每次调用该函数时都调用调度,则自定义钩子可以很简单:

export function useCustomHook() {
  const dispatch          = useDispatch();

  return (key, value) => {
    dispatch(actionCreator.someAction(key, value));
    dispatch(actionCreator.setSomeValue(true));
  };
}