我最近升级了我的 use-debounce 反应包。突破性的变化是钩子返回了一个对象而不是一个数组。我无法更新钩子以使其适用于新更改。 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);
答案 0 :(得分:2)
问题出在这段代码上:
const debouncedSetter = useDebouncedCallback(
// debouncedSetter in this scope is undefined, but linter doesn't catch it
() => debouncedSetter(setInternalState),
durationInMs,
options
);
debouncedSetter
是 undefined
,因为您从未声明过它,因此由于闭包,它会在 callback()
上调用 undefined
,这会导致运行时错误。
如果您将代码更改为下一个代码段,您会注意到 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];
};
答案 1 :(得分:1)
感谢所有发帖的人,这让我找到了答案。工作代码是
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);