React 이벤트 핸들링 & React 성능개선 방법

_dodo_hee·2023년 6월 29일
0

핸드북

목록 보기
17/29

이벤트 처리하기

  • 리액트에서 이벤트의 이름은 카멜(Camel) 표기법을 사용한다.
  • 문자열이 아닌 JSX 함수명으로 전달한다. onClick={함수명}

이벤트 처리(핸들링) 방법

  • 이벤트를 실행할 코드를 그대로 전달하는 것이 아니라 아래 onClick처럼 함수의 형태로 객체를 전달한다.

핸들링 함수 선언

//함수 선언 후 element에 넘겨주는 방법
const App = () => {
    const handleClick = () => {
        console.log("클릭했습니다.");
    }
    return (
        <div>
            <button onClick={handleClick}>클릭하세요</button>
        </div>
    );
};

익명 함수로 처리

// 이벤트 넣어주는 곳에서 익명 함수를 작성하는 방법
const App = () => {
    return (
        <div>
            <button onClick={() => {console.log('클릭했습니다.') }}>클릭하세요</button>
        </div>
    )
}

이벤트 핸들러 인자 전달하기

const App = () => {
    const [username, setUsername] = useState('')
    
    const handlerName= (newName, oldName) => {
    if(newName !== oldName){
    		setUsername(name)
    	}
    }
    
    return (
        <div>
            <h1>{username}님 환영합니다.</h1>
            <MyForm onChange={(event) => { setUsername(event.target.value, name) } }/>
        </div>
    )
}

컴포넌트 간 이벤트 전달하기

사용자가 입력한 정보를 현재 컴포넌트가 아닌 부모 컴포넌트에서 활용해야 하는 경우 이벤트를 props로 전달하여 처리 가능.

// 자식
const MyForm = ({ onChange }) => {
    return (
        <div>
            <span>이름: </span>
            <input onChange={onChange} />
        </div>
    )
}
// 부모
const App = () => {
    const [username, setUsername] = useState('')
    return (
        <div>
            <h1>{username}님 환영합니다.</h1>
            <MyForm onChange={(event) => { setUsername(event.target.value) } }/>
        </div>
    )
}

이벤트 명명법

이벤트를 만들땐, 이름을 자유롭게 설정 할 수 있다.

  • 대게 가독성이 좋은 코드를 만들기 위해 on+동사 , on+명사+동사 형태로 작성한다.
  • 핸들링 함수도 handle or on을 붙여서 작성하는 편이다.

React 랜더링 최적화

우선 최적화를 들어가기전, 컴포넌트의 리랜더링 조건 부터 살피고 가자.

  • 부모에서 전달받은 props가 변경될때
  • 부모 컴포넌트가 리랜더링 될때
  • 자신의 state가 변경 될때

useMemo

React Hook 중 하나로서 React에서 CPU 소모가 심한 함수들을 캐싱하기 위해 사용된다.

컴포넌트 내에 함수 값을 리턴하는데 하나의 변화에도 값을 리턴하는데 많은 시간을 소요한다면?
컴포넌트가 리렌더링 될 때마다 함수가 호출 되면서 많은 시간을 소요하게 된다.

useMemo(()=> 함수, [업데이트 시점을 감지할 값])

엄청 나게 계산이 오래걸리는 함수가 있다고 치자.
그 함수는 원래 컴포넌트가 실행될때마다 함수가 실행되게 되는데,
useMemo를 오래걸리는 함수에 사용하게 되면,
의존성 배열에 넣어둔 값이 변하지 않았을땐, 이전에 참조했던 값을 반환해준다.

useMemo는 종속 변수들이 변하지 않으면 함수를 굳이 다시 호출하지 않고 이전에 반환한 참조값을 재사용 한다.
함수 호출 시간도 세이브할 수 있고 같은 값을 props로 받는 하위 컴포넌트의 리렌더링도 방지할 수 있다.

React.memo 컴포넌트 메모이제이션

React.memo는 Hook이 아니기 때문에 클래스형 컴포넌트에서도 사용할 수 있다.
우리는 이것을 통해 컴포넌트의 props가 바뀌지 않았다면,

리렌더링하지 않도록 설정하여 함수형 컴포넌트의 리렌더링 성능을 최적화 해줄 수 있다.
React.memo는 콜백함수를 이용해 메모이제이션을 적용할지 여부를 판단할 수도 있다.

useCallback

useCallback은 함수 선언을 memoize 하는데 사용된다.

상위 컴포넌트에서 하위컴포넌트로 함수를 props로 넘겨줄 때,
상위 컴포넌트가 리렌더링 될 때마다 상위 컴포넌트 안에 선언된 함수를 새로 생성하기 때문에
그때마다 새 참조 함수를 하위 컴포넌트로 넘겨주게 된다.
이에 따라 하위 컴포넌트도 props가 달라졌으므로 또다시 리렌더링 하게 된다.

그러나 useCallback으로 함수를 선언해주면, 종속 변수들이 변하지 않는 이상 굳이 함수를 재생성하지 않고
이전에 있던 참조 변수를 그대로 하위 컴포넌트에 props로 전달하여,
하위 컴포넌트도 props가 변경되지 않았다고 인지하게 되어 하위 컴포넌트의 리렌더링을 방지할 수 있다.

자식 컴포넌트의 props로 객체를 넘겨줄 경우 변형하지말고 넘겨주기

props의 값으로 객체를 넘겨주는 경우가 많은데, 이때 props로 전달하는 형태에 주의

새로 생성된 객체가 props로 들어가므로 컴포넌트가 리렌더링 될 때마다
새로운 객체가 생성되어 자식 컴포넌트로 전달된다.

props로 전달한 객체가 동일한 값이어도 새로 생성된 객체는
이전 객체와 다른 참조 주소를 가진 객체이기 때문에 자식 컴포넌트는 메모이제이션이 되지않는다.

useState의 함수형 업데이트

기존의 useState를 사용하며, 대부분 setState시에 새로운 상태를 파라미터로 넣어주었다.
setState를 사용할 때 새로운 상태를 파라미터로 넣는 대신, 상태 업데이트를 어떻게 할지 정의해 주는 업데이트 함수를 넣을 수도 있는데,
이렇게 하면 useCallback을 사용할 때 두 번째 파라미터로 넣는 배열에 값을 넣어주지 않아도 된다.

input에 onChange 최적화

debounce를 걸어주는 방법인데, input을 칠때마다 state를 변경해주는게 아닌,
setTimeout으로 시간을 설정해서 시간 설정 해놓은 시간동안 담긴 값을 state에 담아준다.

참고자료
참고자료

profile
무럭무럭 자라나는 도도 개발성장일기

0개의 댓글