React의 이벤트 리스너: 함수 호출과 전달
첫째, 일부 컨텍스트입니다. 평가의 코드 챌린지 섹션에서 다음 요구 사항을 충족하는 "카운터"구성 요소를 작성하라는 요청을 받았습니다.
간단하죠? 내 앱이 로드될 때 내 카운터를 시작하고 카운터의 숫자를 업데이트하기 위해 useEffect 및 useState 후크를 사용해야 한다는 것을 알고 있었습니다(이 경우 매초). w3schools.com의 카운터 의례에 대해 다음 코드를 사용할 수 있었습니다.
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, [count]);
엄청난! 그래서 다음에는 컴포넌트용 JSX를 작성해야 했습니다. 이것이 내가 착륙 한 것입니다.
import React, { useState, useEffect } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, [count]);
return (
<div>
<h1>Counter!</h1>
<div>{count}</div>
<button onClick={setCount((count) => count - 1)}>Decrease</button>
<button onClick={setCount((count) => count + 1)}>Increase</button>
</div>
)
}
export default Counter;
내 생각에 이벤트의 일반적인 순서는 다음과 같이 발생합니다.
renders -> useEffect가 "count"를 1씩 증가시킵니다 -> setState가 "count"의 값을 설정합니다 -> 다시 렌더링합니다 -> useEffect가 다시 실행되고 주기가 계속됩니다
에는 두 개의 버튼이 있으며, 각각은 카운트 상태를 1씩 감소 또는 증가시키는 자체 "onClick"이벤트 리스너가 있습니다. 그 안에 카운트 상태를 감소 또는 증가시키는 화살표 함수를 전달하고 싶었습니다. 나중에 알게 되겠지만 내 구문이 올바르지 않았습니다.
새로 고침 시 구성 요소(및 상위 구성 요소)가 전혀 렌더링되지 않아 이전에 본 적이 없는 콘솔 오류와 함께 빈 페이지가 표시되는 것을 확인했습니다.
구체적으로:
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
원인은 무엇입니까? 의존성 배열이 두 번째 인수로 포함되지 않는 한 useEffect가 무한 루프에서 실행되도록 설정되어 있다는 것을 알고 있었습니다. 두 번째 인수는 [count]로 설정되어 있으므로 useEffect는 내 카운트 상태가 변경될 때마다 실행됩니다. 그것이 문제의 근원이 되어서는 안 됩니다.
내 구성 요소의 버튼을 보면 "onClick"이벤트 리스너가 내 setter 함수 "setCount"를 호출하고 있음을 알 수 있습니다.
setCount((count) => count - 1)
여기서 일어나는 일은 "내 구성 요소를 렌더링하고 useEffect를 실행하여 구성 요소를 다시 렌더링하는 "카운트"상태를 업데이트하고 BTW도 상태를 다시 업데이트합니다."라고 말하는 것입니다. 이렇게 하면 루프가 효과적으로 생성됩니다. 즉, 버튼을 클릭할 때가 아니라 페이지가 렌더링될 때 "setCount"setter 함수가 호출됩니다.
다음은 두 가지 가능한 솔루션입니다.
옵션 #1: 화살표 함수를 onClick 이벤트 핸들러에 전달
import React, { useState, useEffect } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, [count]);
return (
<div>
<h1>Counter!</h1>
<p>{count}</p>
<button onClick={() => setCount(count - 1)}>Decrease</button>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
)
}
export default Counter;
옵션 #2: "setCount"로 상태를 설정하는 이벤트 핸들러 내에서 "핸들러"함수 호출
import React, { useState, useEffect } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, [count]);
const handleDecrease = () => {
setCount((e) => count - 1)
}
const handleIncrease = () => {
setCount((e) => count + 1)
}
return (
<div>
<h1>Counter!</h1>
<p>{count}</p>
<button onClick={handleDecrease}>Decrease</button>
<button onClick={handleIncrease}>Increase</button>
</div>
)
}
export default Counter;
옵션 #1을 사용할지 #2를 사용할지는 전적으로 귀하에게 달려 있지만 일반적으로 한 줄의 코드로 제한된 간단한 작업을 완료할 때 옵션 #1(화살표 기능)을 사용하는 것이 좋습니다.
바라건대, 이것이 실수로 무한 렌더링 루프를 생성하는 것을 방지하는 데 도움이 되는 알림이 되기를 바랍니다.
읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(React의 이벤트 리스너: 함수 호출과 전달), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rreymundi/event-listeners-in-react-calling-vs-invoking-functions-28b7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)