qna-banner-ad

개발자

React 컴포넌트 안 or 밖에서 변수 선언-할당하는 것의 차이가 뭔가요?

2024년 03월 07일조회 835

삽입한 코드는 그냥 위치 설명하기 위한 것이고, 만약에 복잡한 계산식의 결과나, 긴 함수같은 것을 컴포넌트 안에서, 밖에서 선언했을 때의 차이가 명확히 뭔가요..?? (1) 컴포넌트의 state나 props가 바뀔 때마다 해당 컴포넌트가 리렌더링 되면 컴포넌트 내에서 선언-할당한 변수는 재선언-재할당 되나요? 그래서 이 불필요한 재선언-재할당을 막기 위해서 useCallback을 쓰는 건가요..? (2) 아니면 만약 함수의 내용이 state나 props를 사용해서 최신값을 참조해 사용해야 할 경우에 의존성 배열에 이를 넣어서 useCallback을 사용하는 것인지... usecallback의 명확한 목적도 헷갈립니다. (3) 또, 만약 함수 내용이 바뀔 일이 없고 state나 props 값도 사용하지 않으면, 컴포넌트 바깥에서 선언-할당하는 게 좋은 건가요? 성능적인 측면에서 뭐가 좋은 건 지 알려주시면 감사하겠습니다..!

1const a = 10; // 변수 밖
2
3const Example = () => {
4  const a = 10; // 변수 안
5
6  return <></>;
7};
이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 4

인기 답변

김하림님의 프로필 사진

1. 네, React 컴포넌트가 리렌더링 되면 컴포넌트 안에 선언된 변수는 재선언/재할당이 일어납니다. (= 자바스크립트 런타임의 메모리 참조가 변경됩니다.) 2. React가 리렌더링 될 때, 동일한 참조를 유지하고 싶은 변수를 useCallback/useMemo로 관리합니다. 동일한 참조를 유지하는 목적은 성능 향상 목적도 있지만, 의도치 않은 버그를 방지하는 목적도 있습니다. 예를 들어 1번만 실행되야 하는 useEffect가 있다고 가정하겠습니다. useEffect 안에 해당 함수를 실행하는 로직이 있기 때문에, 종속성으로도 해당 함수를 갖고 있습니다. 이 때, 리렌더링이 발생하면서 함수 참조값이 변경되면 useEffect는 종속성이 변경되었으므로 한 번 더 실행됩니다. 이 함수를 useCallback으로 감싸서 참조를 유지해주면, useEffect는 리렌더링이 일어나도 해당 함수가 동일한 참조를 갖고 있으므로 다시 실행되지 않습니다. 3. 네 맞습니다. React 상태에 의존성이 없는 함수들을 외부로 빼면 여러가지 장점이 있습니다. 1) 가독성이 좋아집니다. 코드를 읽을 때 React에 의존성이 없는 함수라는 것을 개발자가 바로 파악할 수 있습니다. 2) 테스트가 용이합니다. React 스코프 안에 정의된 함수는 export되지 않아서 단위 테스트 도구(ex: Jest)로 테스트가 불가능합니다. 3) 유지보수에 용이합니다. 함수를 별도의 폴더에 분리해서 관리할 수 있기 때문에 관심사가 분리되며 여러 곳에서 재사용하기 좋습니다. 저희 팀은 공통으로 사용하는 함수를`utils`에, 비즈니스에 관련된 함수를 `services`에 분리해서 관리하고 있습니다. 프로젝트가 소규모일 땐 관심사 분리가 크게 와닿지 않았는데 프로젝트가 커질수록 관심사 분리의 중요성에 대해서 느끼고 있습니다.

포크코딩님의 프로필 사진

밖, 안 구분은 해당 변수가 어디 메모리 부분에 쓰여지냐 차이입니다. 러스트나 C/C++을 쓴다면 모를까 이는 자바스크립트 엔진이 알아서 해주므로 신경쓸 부분은 아닙니다. 1. 네, useMemo, useCallback 둘 다 같은 궤입니다. 변수냐 함수 그 자체냐 차이죠. 2. 어떻게 사용하냐는 개발자 마음입니다. useCallback 훅의 목적은 캐싱, 메모이제이션이라 부르는 최적화 기법을 위해 사용됩니다. 3. 아마 직관적으로 알고 계신듯 합니다. 보통 그런 친구들을 모아서 lib 폴더 아래 utils.ts 같은 파일에 모아둔 경우를 보셨을 겁니다. 같은 경우입니다. 성능적인 측면에서 좋은 점: i) CPU를 많이 사용하는 무거운 계산을 반복할 필요가 없어집니다. ii) 함수를 호출하는데 필요한 콘텍스트 체인지 등이 줄어듭니다.

김하늘님의 프로필 사진

질문주신 내용 모두 이론적으론 그렇습니다. 그런데 어지간해선 실제론 영향이 정말 미미합니다. 메모이제이션, 캐싱을 한다고 하니 뭔가 대단한 최적화나 성능 개선을 해줄 것만 같지만 대부분의 경우 안해도 무방합니다. 오히려 손해를 보는 경우도 있습니다. (대부분 혹은 모든 프로그래밍 기법은 트레이드오프가 있습니다.) 전 성능 때문이라기보단 가독성 때문에 코드의 위치나 적절한 쓰임이 중요하다고 생각합니다. 누군가 다른 설명이나 주석없이도 이 코드를 읽었을 때 쉽게 이해하기 위함이죠. 이를테면 '함수가 이 파일에 선언된 것을 보니 여러 컴포넌트에서 쓰이는 유틸성 함수인가보다', 'useMemo을 쓴 것을 보니 뭔가 메모이제이션이 필요했나보군', '얘는 컴포넌트 안에서 지역 상태로 관리해야만 하나보군' 등이요.

준님의 프로필 사진

리액트도 그저 자바스크립트로 만들어진 프레임웍입니다 자바스크립트의 scope에 대해 공부해보시는게 크게 도움되실것 같아요

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 03월 07일

React 컴포넌트 안 밖에서의 변수 선언-할당은 다음과 같이 이해하시면 됩니다: 1. **컴포넌트 내부에 선언한 변수**: React 컴포넌트는 랜더링될 때마다 컴포넌트 함수가 새롭게 실행되므로, 매번 재선언과 재할당이 일어납니다. 따라서 state나 props가 변화하여 컴포넌트가 재랜더링될 때마다 해당 변수는 새롭게 계산되고 할당됩니다. 2. **컴포넌트 외부에 선언한 변수**: 한 번만 선언되고 값이 변경되지 않습니다. 이런 방식은 React의 라이프사이클에 영향을 받지 않기 때문에, 컴포넌트가 리렌더링 되어도 재할당이나 재계산이 일어나지 않습니다. 그리고 useCallback에 대해서는: `useCallback`은 메모이제이션된 버전의 callback 함수를 반환합니다. 그럼으로써 불필요한 함수 생성을 방지하여 성능 최적화를 돕습니다. 주로 이벤트 핸들러 같은 곳에서 사용하는데, 의존성 배열 내부의 값들이 바뀔 경우에만 새로운 함수가 생성되고, 그렇지 않다면 메모이제이션된 함수를 재사용합니다. 따라서 props나 state를 사용하는 경우에 useCallback을 사용하며, 명확한 목적은 불필요한 리렌더링과 함수 생성을 피하여 성능을 최적화하는 것입니다. 컴포넌트 바깥에서 선언할지 안에서 선언할지는 상황에 따라 달라집니다. 만약에 함수 내부에서 컴포넌트의 prop나 state를 참조하지 않고, 그리고 리렌더링에 따른 재계산이 필요없는 경우라면 컴포넌트 바깥에서 선언하는 것이 좋습니다. 이 방식은 컴포넌트 내부보다 메모리 할당과 계산을 절약하기 때문에 약간 더 효율적일 수 있습니다. 그러나 특정 prop이나 state에 의존하는 복잡한 계산이 필요하거나, 함수가 동적으로 변경되야 하는 경우라면 컴포넌트 내부에서 `useMemo` 또는 `useCallback`을 사용하여 선언해야 합니다. 결론적으로 핵심은 되도록 불필요한 재선언-재할당을 피하고, 가능하다면 컴포넌트 외부에서 변수를 선언하는 것입니다. 하지만 상황에 따라 `useMemo`, `useCallback` 같은 훅을 사용해야 할 때도 있습니다. 이러한 선택은 코드의 목적과 복잡성, 그리고 성능 요구조건에 따라 달라집니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!