【问题标题】:React returning a function in a custom hook, whose internal hook returns an objectReact 在自定义钩子中返回一个函数,其内部钩子返回一个对象
【发布时间】:2021-02-10 17:11:16
【问题描述】:

我最近升级了我的 use-debounce react 包。重大变化是钩子返回了一个对象而不是一个数组。我无法更新钩子以使其适用于新更改。 I have created a codesandbox to demonstrate the issue,设置状态失败,因为从钩子返回的设置器配置不正确。出于沙箱的目的,我将钩子组件放入主组件中,以便所有信息都集中在一个位置。

错误是setState is not a function

如果你不想看,这里是沙盒中的代码

const Input = () => {
  // hook that would normally be in a seperate component
  const useDebouncedState = (
    initialState,
    durationInMs = 200,
    options = {}
  ) => {
    const [internalState, setInternalState] = useState(initialState);
    const debouncedSetter = useDebouncedCallback(
      () => debouncedSetter.callback(setInternalState),
      durationInMs,
      options
    );
    return [internalState, debouncedSetter];
  };

  // this would be set in the main components
  const [searchText, setSearchText] = useDebouncedState("", 200, {
    maxWait: 1000
  });

  // this is where i set
  return (
    <>
      <input type="text" onChange={(e) => setSearchText(e.target.value)} />
      <h1>{searchText}</h1>
    </>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<Input />, rootElement);

【问题讨论】:

  • 有什么问题?
  • 抱歉忘记提了。 "setSearchText 不是函数"
  • 你看看你的去抖动回调代码,和例子中使用去抖动的代码,是很不一样的。也许你应该再回到这个例子?

标签: reactjs react-hooks


【解决方案1】:

问题在于这段代码:

const debouncedSetter = useDebouncedCallback(
  // debouncedSetter in this scope is undefined, but linter doesn't catch it
  () => debouncedSetter(setInternalState),
  durationInMs,
  options
);

debouncedSetterundefined,因为您从未声明它,因此由于闭包,它将在 undefined 上调用 callback(),这会导致运行时错误。

如果您将代码更改为下一个 sn-p,您会注意到 linting 警告:

const useDebouncedState = (initialState, durationInMs = 200, options = {}) => {
  const [internalState, setInternalState] = useState(initialState);
  const callback = useDebouncedCallback(
    // 'debouncedSetter' is not defined
    () => debouncedSetter(setInternalState),
    durationInMs,
    options
  );
  return [internalState, callback];
};

【讨论】:

    【解决方案2】:

    感谢所有发帖的人,这让我得到了答案。工作代码是

    import React, { useState } from "react";
    import ReactDOM from "react-dom";
    import useDebouncedCallback from "use-debounce/lib/useDebouncedCallback";
    
    const Input = () => {
      // hook that would normally be in a seperate component
      const useDebouncedState = (
        initialState,
        durationInMs = 200,
        options = {}
      ) => {
        const [internalState, setInternalState] = useState(initialState);
        const debouncedSetter = useDebouncedCallback(
          setInternalState,
          durationInMs,
          options
        );
        return [internalState, debouncedSetter];
      };
    
      // this would be set in the main components
      const [searchText, setSearchText] = useDebouncedState("", 800, {
        maxWait: 1000
      });
    
      // this is where i set
      return (
        <>
          <input
            type="text"
            onChange={(e) => setSearchText.callback(e.target.value)}
          />
          <h1>{searchText}</h1>
        </>
      );
    };
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<Input />, rootElement);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-20
      • 2020-07-13
      • 2020-01-23
      • 2020-06-19
      • 2020-08-26
      • 2020-08-20
      • 2022-01-26
      • 1970-01-01
      相关资源
      最近更新 更多