입력하는 동안 ReactJs가 변경 시 지연
사용자가 입력하는 문자열을 유지하기 위해 상태를 변경해야 합니다.그러나 사용자가 입력을 멈출 때까지 작업을 지연시키고 싶습니다.하지만 어떻게 둘 다 할 수 있는지 정확히 짚어낼 수가 없어요.
따라서 사용자가 입력을 중지하면 액션을 트리거하고 싶지만 그 전에는 트리거하지 않습니다.좋은 의견이라도 있나?
리액트 후크 및 기능 구성 요소 포함
하려면 , 「 」를 합니다.useState
후크를 눌러 사용자가 입력하는 텍스트를 저장합니다.그런 다음 입력 값에 해당 상태를 지정합니다. 꼭 '나', '나'를 하세요.setState
onChange
이치노그렇지 않으면 입력 값은 변경되지 않습니다.
, 「」를 합니다.useEffect
을 setTimeout
「 」, 「 」를 합니다.useEffect
useEffect
후크 및 의존관계 배열에 입력값과 함께 변수를 지정합니다.「 」에 .useEffect
사용해야 한다setTimeout
원하는 지연 시간 후에 액션을 트리거합니다.,, 음, 음, 음, 음, 음, 음에 .useEffect
는 타임아웃 세트를 클리어하는 정리 함수를 반환해야 합니다.이렇게 하면 더 이상 사용자와 관련이 없는 입력 값에 대한 작업이 수행되지 않습니다.
아래는 위의 단계를 사용하여 사용자가 입력하는 문자열을 표시하도록 하고 사용자가 입력을 멈춘 후 500ms 후에 완료된 문자열을 표시하는 앱의 간단한 예입니다.
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>
</>
);
}
사용할 필요가 있는 사운드setTimeout
사용자가 텍스트를 입력하는 즉시 타이머를 시작합니다.사용자가 다른 문자를 입력한 경우 타이머를 재시작합니다.타이머가 완료되기 전에 사용자가 다시 입력하지 않으면 체크박스를 전환하는 작업이 실행됩니다.
class App extends React.Component {
constructor() {
super();
this.state = {
text: '',
checked: false
};
this.timer = null;
}
componentDidUpdate (prevProps, prevState) {
if(prevState.text !== this.state.text) {
this.handleCheck();
}
}
onChange = e => {
this.setState({
text: e.target.value
});
};
handleCheck = () => {
// Clears running timer and starts a new one each time the user types
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.toggleCheck();
}, 1000);
}
toggleCheck = () => {
this.setState( prevState => ({ checked: !prevState.checked }));
}
render () {
return (
<div>
<input value={this.state.text} onChange={this.onChange} placeholder="Start typing..." /><br/>
<label>
<input type="checkbox" checked={this.state.checked} onChange={this.toggleCheck} />
Toggle checkbox after user stops typing for 1 second
</label>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
중는 당신의 '자신에게'에게 '자신'은 '자신'입니다.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} />
)
}
}
리액트 후크 및 기능 구성 요소 포함
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); }} />
리액트 훅 포함 - useRef
const timer = useRef(null)
useEffect(() => {
clearTimeout(timer.current)
timer.current = setTimeout(() => {
// your logic
},1000)
},[value])
첫 번째 경우를 제외한 모든 상태 업데이트를 호출합니다.
저도 같은 요.setTimeout
하는 데 이 될 것 .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)} />
);
};
이 목적을 위해 특별히 커스텀훅을 작성하여 useState 훅과 같이 사용할 수 있습니다.이건 jnforja의 대답의 연장선상에 더 가깝습니다.
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)
필요에 따라서, 이 문서를 참조해, 실장에 대해 설명할 수도 있습니다.
onChange 이벤트를 디바운스할 수 있습니다(사용자가 onChange 이벤트를 입력하면 실행되지 않습니다).
경고 - 렌더에 함수를 만드는 것은 잘못된 작업 방식입니다.나는 해결책을 설명하기 위해 그것을 했다.보다 안전한 해결책은 디버깅된 핸들러를 생성자에 작성하는 클래스 컴포넌트를 사용하는 것입니다.
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} />
)
}
}
다음 예
function DebouncedInput (props) {
const { onChange, delay = 300, ...rest } = props;
return (
<input
{...rest}
onChange={ _.debounce(onChange, delay)}
/>
)
}
function App() {
return (
<div>
<DebouncedInput
type="text"
placeholder="enter"
delay={2000}
onChange={() => console.log('changing')}
/>
</div>
)
}
ReactDOM.render(
<App/>,
document.querySelector('#app')
);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
콜 변경 핸들러 함수의 지연에는 debounce 및 lodash 라이브러리의 throttle을 사용할 수 있습니다.다음 코드는 debounce를 기반으로 합니다.스로틀 기능에도 동일한 코드를 사용할 수 있습니다.데바운스: X밀리초 이후까지 함수 호출 지연 스로틀: X밀리초마다 최대 1회 함수를 호출합니다.
샘플 코드:
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>
);
}
이 건에 대해 npm 패키지를 작성했습니다.제공된 훅을 사용하여 즉시값과 지연값을 모두 얻을 수 있습니다.
https://www.npmjs.com/package/use-delayed-search
언급URL : https://stackoverflow.com/questions/53071774/reactjs-delay-onchange-while-typing
'programing' 카테고리의 다른 글
익명 객체에 JSON 직렬화 해제 (0) | 2023.02.11 |
---|---|
IIS 7 php-cgi의 WordPress를 통한 CPU 사용 (0) | 2023.02.11 |
XMLHttpRequest 액세스가 Angular로 거부됨10 미만의 IE 버전에서는 JS (0) | 2023.02.11 |
wp_list_categories()에서 제목을 삭제하는 중 (0) | 2023.02.11 |
Internet Explorer 11이 Authorization 헤더를 대체합니다. (0) | 2023.02.11 |