React 使用 debounce 和 setState
React use debounce with setState
背景
假设我们都知道 lodash
中的 debounce
函数。
如果用户快速输入1
、12
、123
、1234
,它允许我们只进行一次警报,1234
,经过一定的延迟时间后。
这个比较常用来减少请求量,优化。
描述
对于普通输入字段,我们可以使用那种 debounce
并且有效。
问题:一旦我们在与 debounce
相同的回调中添加 setState
,debounce
将无法正常工作。
有谁知道原因吗?
import React, { useState } from "react";
import "./styles.css";
import { debounce } from "lodash";
export default function App() {
const [input, setInput] = useState("");
const debouceRequest = debounce(value => {
alert(`request: ${value}`);
}, 1000);
const onChange = e => {
setInput(e.target.value); // Remove this line will lead to normal debounce
debouceRequest(e.target.value);
};
return (
<div className="App">
<input onChange={onChange} />
</div>
);
}
试试这个(使用 useCallback):
import React, { useState, useCallback } from "react";
import "./styles.css";
import { debounce } from "lodash";
const request = debounce(value => {
alert(`request: ${value}`);
}, 1000);
export default function App() {
const [input, setInput] = useState("");
const debouceRequest = useCallback(value => request(value), []);
const onChange = e => {
debouceRequest(e.target.value);
setInput(e.target.value); // Remove this line will lead to normal denounce
};
return (
<div className="App">
<input onChange={onChange} />
</div>
);
}
背景
假设我们都知道 lodash
中的 debounce
函数。
如果用户快速输入1
、12
、123
、1234
,它允许我们只进行一次警报,1234
,经过一定的延迟时间后。
这个比较常用来减少请求量,优化。
描述
对于普通输入字段,我们可以使用那种 debounce
并且有效。
问题:一旦我们在与 debounce
相同的回调中添加 setState
,debounce
将无法正常工作。
有谁知道原因吗?
import React, { useState } from "react";
import "./styles.css";
import { debounce } from "lodash";
export default function App() {
const [input, setInput] = useState("");
const debouceRequest = debounce(value => {
alert(`request: ${value}`);
}, 1000);
const onChange = e => {
setInput(e.target.value); // Remove this line will lead to normal debounce
debouceRequest(e.target.value);
};
return (
<div className="App">
<input onChange={onChange} />
</div>
);
}
试试这个(使用 useCallback):
import React, { useState, useCallback } from "react";
import "./styles.css";
import { debounce } from "lodash";
const request = debounce(value => {
alert(`request: ${value}`);
}, 1000);
export default function App() {
const [input, setInput] = useState("");
const debouceRequest = useCallback(value => request(value), []);
const onChange = e => {
debouceRequest(e.target.value);
setInput(e.target.value); // Remove this line will lead to normal denounce
};
return (
<div className="App">
<input onChange={onChange} />
</div>
);
}