React 이벤트 핸들러: 함수 호출과 전달

4484 단어
이 게시물은 2단계 평가를 완료하는 동안 우연히 발견한 오류와 문제를 이해하고 해결하기 위해 취한 단계에 초점을 맞출 것입니다.

첫째, 일부 컨텍스트입니다. 평가의 코드 챌린지 섹션에서 다음 요구 사항을 충족하는 "카운터"구성 요소를 작성하라는 요청을 받았습니다.
  • DOM이 로드될 때 1씩 증가하여 렌더링 및 계산 시작
  • 클릭 시 카운트를 1씩 줄이는 버튼이 포함되어 있습니다
  • .
  • 클릭 시 카운트를 1씩 증가시키는 버튼이 포함되어 있습니다
  • .

    간단하죠? 내 앱이 로드될 때 카운터를 시작하고 매초마다 숫자를 업데이트하려면 useEffect 및 useState 후크를 사용해야 한다는 것을 알고 있었습니다. 나는 w3schools.com의 Counter 호의에 대해 다음 코드를 사용할 수 있었습니다.

    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;
    


    이벤트의 일반적인 순서는 다음과 같습니다.

    "Counter"렌더링 -> useEffect가 "count"를 1씩 증가 -> setState가 "count"값을 설정 -> "Counter"다시 렌더링 -> useEffect가 다시 실행되고 주기가 계속됨

    "카운터"에는 카운터를 1씩 줄이거 나 늘리는 자체 "onClick"이벤트 리스너가 있는 두 개의 버튼이 있습니다.

    새로 고침 시 Counter 구성 요소(및 상위 구성 요소)가 전혀 렌더링되지 않아 이전에 본 적이 없는 콘솔 오류와 함께 빈 페이지가 표시되는 것을 확인했습니다.



    구체적으로:

    Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
    


    원인은 무엇입니까? 종속성 배열이 [count]로 설정된 두 번째 인수로 포함되지 않는 한 useEffect가 무한 루프에서 실행되도록 설정되어 있으므로 useEffect는 "count"에 대한 내 상태가 변경될 때마다 실행됩니다. 그것이 문제의 근원이 되어서는 안 됩니다.

    내 구성 요소의 버튼을 보면 "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(화살표 기능)을 사용하는 것이 좋습니다.

    바라건대, 이것이 실수로 무한 렌더링 루프를 생성하는 것을 방지하는 데 도움이 되는 알림이 되기를 바랍니다.

    읽어 주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기