【发布时间】:2019-12-24 03:11:16
【问题描述】:
我正在尝试创建一个其值去抖动的输入字段(以避免不必要的服务器访问)。 第一次渲染我的组件时,我从服务器获取它的值(有一个加载状态和所有)。
这是我所拥有的(为了示例的目的,我省略了不相关的代码)。
这是我的去抖钩子:
export function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
(我从:https://usehooks.com/useDebounce/ 得到这个)
对,这是我的组件以及我如何使用 useDebounce 钩子:
function ExampleTitleInput(props) {
const [title, setTitle] = useState(props.title || "");
const [lastCommittedTitle, setLastCommittedTitle] = useState(title);
const [commitsCount, setCommitsCount] = useState(0);
const debouncedTitle = useDebounce(title, 1000);
useEffect(() => {
setTitle(props.title || "");
}, [props.title]);
useEffect(() => {
if (debouncedTitle !== lastCommittedTitle) {
setLastCommittedTitle(debouncedTitle);
setCommitsCount(commitsCount + 1);
}
}, [debouncedTitle, lastCommittedTitle, commitsCount]);
return (
<div className="example-input-container">
<input
type="text"
value={title}
onChange={e => setTitle(e.target.value)}
/>
<div>Last Committed Value: {lastCommittedTitle}</div>
<div>Commits: {commitsCount}</div>
</div>
);
}
这里是父组件:
function App() {
const [title, setTitle] = useState("");
useEffect(() => {
setTimeout(() => setTitle("This came async from the server"), 2000);
}, []);
return (
<div className="App">
<h1>Example</h1>
<ExampleTitleInput title={title} />
</div>
);
}
当我运行这段代码时,我希望它在第一次(仅)时忽略去抖动值的变化,所以它应该显示提交次数为 0,因为该值是从 props 传递的。应跟踪任何其他更改。抱歉,我度过了漫长的一天,此时我有点困惑(我想我一直盯着这个“问题”太久了)。
我已经创建了一个示例:
https://codesandbox.io/s/zen-dust-mih5d
它应该显示提交的数量为 0,并且值设置正确,没有去抖改变。
我希望我说得通,如果我能提供更多信息,请告诉我。
编辑
这完全符合我的预期,但是它给了我“警告”(注意 deps 数组中缺少依赖项):
function ExampleTitleInput(props) {
const [title, setTitle] = useState(props.title || "");
const [lastCommittedTitle, setLastCommittedTitle] = useState(title);
const [commitsCount, setCommitsCount] = useState(0);
const debouncedTitle = useDebounce(title, 1000);
useEffect(() => {
setTitle(props.title || "");
// I added this line here
setLastCommittedTitle(props.title || "");
}, [props]);
useEffect(() => {
if (debouncedTitle !== lastCommittedTitle) {
setLastCommittedTitle(debouncedTitle);
setCommitsCount(commitsCount + 1);
}
}, [debouncedTitle]); // removed the rest of the dependencies here, but now eslint is complaining and giving me a warning that I use dependencies that are not listed in the deps array
return (
<div className="example-input-container">
<input
type="text"
value={title}
onChange={e => setTitle(e.target.value)}
/>
<div>Last Committed Value: {lastCommittedTitle}</div>
<div>Commits: {commitsCount}</div>
</div>
);
}
这里是:https://codesandbox.io/s/optimistic-perlman-w8uug
这行得通,很好,但我担心警告,感觉好像我做错了什么。
【问题讨论】:
标签: javascript reactjs react-hooks