簡體   English   中英

React 在自定義鈎子中返回 function,其內部鈎子返回 object

[英]React returning a function in a custom hook, whose internal hook returns an object

我最近升級了我的使用去抖反應 package。 重大變化是鈎子返回了 object 而不是數組。 我無法更新鈎子以使其適用於新更改。 我創建了一個代碼框來演示該問題,其中設置 state 失敗,因為從鈎子返回的設置器配置不正確。 出於沙箱的目的,我將鈎子組件扔到了主組件中,這樣所有信息都將集中在一個位置。

錯誤是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);

問題在於這段代碼:

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

debouncedSetterundefined的,因為您從未聲明過它,因此由於閉包,它將在undefined時調用callback() ,這會導致運行時錯誤。

如果您將代碼更改為下一個片段,您會注意到 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];
};

感謝所有發帖的人,這讓我得到了答案。 工作代碼是

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM