我需要改变状态以保持用户正在输入的字符串。然而,我想延迟一个动作直到用户停止输入。但我不太清楚如何同时做到这两点。所以当用户停止输入时,我希望触发一个动作,但不是在此之前。有什么建议吗?
n7taea2i1#
要保留用户正在键入的字符串,请使用useState挂钩来存储用户正在键入的文本。然后将该状态赋予input的值。还要确保在input的onChange事件处理程序上使用setState,否则input值不会更改。要想在用户停止输入后的某个时间触发一个动作,可以将useEffect挂钩与setTimeout一起使用,在这种情况下,我们希望在输入值发生变化时触发useEffect,因此我们将创建一个useEffect钩子,并在其依赖数组上为它提供带有input值的变量。指定给useEffect的函数应使用setTimeout在所需的延迟时间后触发动作。此外,指定给useEffect的函数应返回清除超时设置的清除函数。这可避免对不再与用户相关的输入值执行动作。下面是一个应用程序的小例子,它使用上述步骤来保持用户正在键入的字符串可见,并在用户停止键入500ms后显示完成的字符串。
useState
onChange
setState
useEffect
setTimeout
function App() { const [query, setQuery] = useState(""); const [displayMessage, setDisplayMessage] = useState(""); useEffect(() => { const timeOutId = setTimeout(() => setDisplayMessage(query), 500); return () => clearTimeout(timeOutId); }, [query]); return ( <> <input type="text" value={query} onChange={event => setQuery(event.target.value)} /> <p>{displayMessage}</p> </> ); }
bbmckpt72#
用户输入文本后,您需要使用setTimeout来启动计时器。如果用户输入另一个字符,则重新启动计时器。如果用户在计时器完成之前没有再次输入,则它将触发一个切换复选框的操作:第一个
nxowjjhe3#
一种方法是让onChange处理程序执行两个函数:
示例代码:
import debounce from 'lodash.debounce'; class Foo extends React.Component { constructor() { super() this.state = { value: '' } // Delay action 2 seconds this.onChangeDebounced = debounce(this.onChangeDebounced, 2000) } handleInputChange = (e: Event) => { // Immediately update the state this.setState({ value: e.target.value }) // Execute the debounced onChange method this.onChangeDebounced(e) } onChangeDebounced = (e: Event) => { // Delayed logic goes here } render() { return ( <input onChange={this.handleInputChange} value={this.state.value} /> ) } }
k4aesqcs4#
带React挂钩和函数组件
const [timer, setTimer] = useState(null); function changeDelay(change) { if (timer) { clearTimeout(timer); setTimer(null); } setTimer( setTimeout(() => { console.log(change); }, 3000) ); }
输入
<input type="text" onChange={(e) => { changeDelay(e.target.value); }} />
vc9ivgsu5#
带React钩-使用参考
const timer = useRef(null) useEffect(() => { clearTimeout(timer.current) timer.current = setTimeout(() => { // your logic },1000) },[value])
smdncfj36#
实际上,我也有同样的问题,但一点setTimeout可以帮助我检查ref的第一次挂载:
ref
import React, {useState, useEffect, useRef} from "react"; const Search = () => { const filterRef = useRef(); // use ref to call the API call all time except first time const [serpQuery, setSerpQuery] = useState(''); useEffect(() => { let delayTimeOutFunction; if(!filterRef.current) { filterRef.current = true; } else { // componentDidMount equivalent delayTimeOutFunction = setTimeout(() => { console.log('call api: ', serpQuery) }, 700); // denounce delay } return () => clearTimeout(delayTimeOutFunction); }, [serpQuery]); return ( <input value={serpQuery} onChange={e => setSerpQuery(e.target.value)} /> ); };
iovurdzv7#
您可以专门为此构建一个自定义钩子,并像useState钩子一样使用它。
import { useEffect, useState } from "react"; const useDebounce = (initialValue = "", delay) => { const [actualValue, setActualValue] = useState(initialValue); const [debounceValue, setDebounceValue] = useState(initialValue); useEffect(() => { const debounceId = setTimeout(() => setDebounceValue(actualValue), delay); return () => clearTimeout(debounceId); }, [actualValue, delay]); return [debounceValue, setActualValue]; }; export default useDebounce;
并像使用延迟值的useState挂接一样使用它
const [value, setValue] = useDebounce('',1000)
如果需要,您还可以查看this文章,其中解释了实现。
lxkprmvk8#
您可以对onChange事件进行去抖动(如果用户正在键入,则onChange事件不会执行)警告-请记住,在呈现时创建函数是一个不好的做法。我这样做是为了说明解决方案。一个更安全的解决方案是使用一个类Component,它在其构造函数上创建去抖动处理程序。
class DebouncedInput extends React.Component { constructor() { super(); // Creating the debouncedOnChange to avoid performance issues this._debouncedOnChange = _.debounce( this.props.onChange, this.props.delay ); } render () { const { onChange, delay, ...rest } = this.props; return ( <input onChange={this._debouncedOnChange} {..rest} /> ) } }
示例如下第一次
kognpnkq9#
你可以使用lodash延迟库的debounce和throttle来调用change handler函数,下面的代码是基于debounce的。同样的代码也可以用于throttle函数。Debounce:延迟调用函数,直到X毫秒后。节流:每X毫秒最多调用一次函数样本代码:
import React,{useEffect, useState, useMemo} from "react" import debounce from "lodash.debounce"; export default function App() { const [search, setSearch] = useState(""); const handleChangeSearch = ({ target }) => { setSearch(target.value); }; const debouncedChangeHandler = useMemo( () => debounce(handleChangeSearch, 500), [] ); useEffect(() => { return () => { debouncedChangeHandler.cancel(); } }, []); return ( <div className="App"> <label > Search: <input sx={{ display: { xs: "none", md: "block" } }} onChange={debouncedChangeHandler} name="search" type="text" placeholder="search..." /> </label > </div> ); }
9条答案
按热度按时间n7taea2i1#
带React挂钩和函数组件
要保留用户正在键入的字符串,请使用
useState
挂钩来存储用户正在键入的文本。然后将该状态赋予input的值。还要确保在input的onChange
事件处理程序上使用setState
,否则input值不会更改。要想在用户停止输入后的某个时间触发一个动作,可以将
useEffect
挂钩与setTimeout
一起使用,在这种情况下,我们希望在输入值发生变化时触发useEffect
,因此我们将创建一个useEffect
钩子,并在其依赖数组上为它提供带有input值的变量。指定给useEffect
的函数应使用setTimeout
在所需的延迟时间后触发动作。此外,指定给useEffect
的函数应返回清除超时设置的清除函数。这可避免对不再与用户相关的输入值执行动作。下面是一个应用程序的小例子,它使用上述步骤来保持用户正在键入的字符串可见,并在用户停止键入500ms后显示完成的字符串。
bbmckpt72#
用户输入文本后,您需要使用
setTimeout
来启动计时器。如果用户输入另一个字符,则重新启动计时器。如果用户在计时器完成之前没有再次输入,则它将触发一个切换复选框的操作:第一个
nxowjjhe3#
一种方法是让
onChange
处理程序执行两个函数:示例代码:
k4aesqcs4#
带React挂钩和函数组件
输入
vc9ivgsu5#
带React钩-使用参考
smdncfj36#
调用除第一次之外的每个状态更新:
实际上,我也有同样的问题,但一点
setTimeout
可以帮助我检查ref
的第一次挂载:iovurdzv7#
您可以专门为此构建一个自定义钩子,并像useState钩子一样使用它。
并像使用延迟值的useState挂接一样使用它
如果需要,您还可以查看this文章,其中解释了实现。
lxkprmvk8#
您可以对onChange事件进行去抖动(如果用户正在键入,则onChange事件不会执行)
警告-请记住,在呈现时创建函数是一个不好的做法。我这样做是为了说明解决方案。一个更安全的解决方案是使用一个类Component,它在其构造函数上创建去抖动处理程序。
示例如下
第一次
kognpnkq9#
你可以使用lodash延迟库的debounce和throttle来调用change handler函数,下面的代码是基于debounce的。同样的代码也可以用于throttle函数。Debounce:延迟调用函数,直到X毫秒后。节流:每X毫秒最多调用一次函数
样本代码: