본문 바로가기

Front-End: Web/React.js

(17)
[React] Error: Rendered more hooks than during the previous render 이슈/원인 Rendered more hooks than during the previous render 이전 렌더링에서 호출된 hooks보다, 현재 렌더링에서 호출된 hooks가 더 많은 경우에 발생하는 에러 React는 Hook이 호출되는 순서에 의존한다 React는 Hook이 호출되는 순서에 의존한다. Hook이 함수의 상태를 기억하기 위해서, 호출 순서를 이용하여 함수의 상태를 기억했다가 이전의 상태를 가져온다. 따라서 렌더링되는 순서가 동일해야 React가 locale state를 각 Hook에 연동할 수 있다. 즉, Hook가 매 렌더링마다 동일한 순서로 동일한 개수만큼 호출을 보장 받아야한다. 그래서 Hook을 조건문, 반복문, 함수 안에서 작성하는게 금지되어 있고, 컴포넌트 최상단에서 호출하..
_app와 _document Recap _app과 _document Next.js의 기본 페이지 페이지에 공통적으로 적용될 내용들을 작성 _app은 로적, 전역 스타일 등 컴포넌트에 공통 데이터를 다룸 _document는 공통적으로 적용할 HTML 마크업을 중심으로 다룸 _app 서버로 요청이 들어왔을 때 가장 먼저 실행되는 컴포넌트 페이지에 적용할 공통 레이아웃의 역할을 함 주 사용 목적 모든 컴포넌트에 공통적으로 적용할 속성 관리 function MyApp({ Component, pageProps }) { return } export default MyApp 규칙 Component 속성값 → 서버에서 요청한 페이지 ex. localhost:3000/home 접속 시, Component는 home 컴포넌트임 pageProps 는 ..
"ElementRef"로 useRef 타입을 더 강력하게 지정하기 기본 요소에서 useRef 를 사용하는 것은 다소 어려울 수 있다. 왜냐하면 대상 요소의 타입을 지정해야만 하는데, 어떤 타입을 사용해야하는지 명확하지 않기 때문이다. import { useRef } from "react"; const Component = () => { // What goes here? const audioRef = useRef(null); return Hello; }; 간단한 해결법으로는 ref 타입에 마우스를 올리고, 어떤게 들어갈 수 있는지 체크해보는 것이 있다. 근데 더 쉬운 방법이 있다! ElementRef 가 뭘까? 리액트에서 타입 도우미로 ElementRef를 사용할 수 있는데, ElementRef를 사용하면 대상 요소에서 타입을 쉽게 추출할 수 있다. import { us..
Lazy loading을 쓸 때는 Suspense를 사용합시다! !!!!!!!!!!! Lazy loading을 사용할 때, Suspense와 함께 사용해야 한다! 이걸 몰라서 에러 잡는데 시간 꽤 걸렸다.. lazy를 쓸때는 suspense 를 사용합시다.. 참고 자료 React.lazy 사용해보기 FE Lazy Loading 적용기 - 트렌비 기술블로그
useRef 란? (feat. RefObject) useRef useRef? React Hook의 일종 인자로 넘어온 초기값을 useRef 객체의 .current property에 저장한다. 사용 용도 DOM 객체에 직접 접근하여 내부 값을 변경할 때 focus() 메서드를 사용해야할 때 값이 변경되어도 컴포넌트에 리렌더링이 일어나지 않도록 할 때 useRef 는 내용이 변경되어도 변경되었다는 사실을 알려주지 않는다. .current property를 변경시키면 리렌더링을 발생시키지 않음. 그래서 로컬 변수 용도로도 사용할 수 있다. ex. Input과 같은 태그에서 값을 입력할 때마다 컴포넌트에 리렌더링이 일어나지 않도록 하고 싶은 경우 그저 함수의 초기값을 .current에 저장한다고 보면 된다. useRef의 반환 타입 종류인 MutableReOb..
useMutation 사용 시 컴포넌트 리렌더링 줄이기 문제점? 로그인페이지에서 로그인 버튼을 누르면 모든 컴포넌트가 리렌더링되는 문제가 발생한다. useMutation의 반환값들 export interface MutationResult { data?: TData | null; error?: ApolloError; loading: boolean; called: boolean; client: ApolloClient; } 이 중에서 loading 이 리렌더링을 발생시킨다. 따라서 useMutation을 작성한 컴포넌트 내에서 무조건 리렌더링이 발생한다. 컴포넌트의 리렌더링을 줄이고 싶다면, props를 전달해서 하위 컴포넌트에서 useMutation을 실행시키자. 프로젝트 적용하기 이전 코드 여기서 onLogin을 내려주는게 아니라, refs와 setErrorM..
forwardRef 사용법 (+여러 ref들 전달하기) 공부하게된 계기 커스텀 훅인 useInput을 사용하여 인풋을 관리하니 편하긴 하지만, value가 달라질 때마다 인풋 컴포넌트를 포함한 대부분의 모든 컴포넌트들이 리렌더링된다. 왜냐하면 로그인 페이지에서 header, body, footer로 나뉘는데 email, password 인풋의 value들을 header, body, footer를 묶어주는 로그인페이지 컴포넌트에서 관리하기 때문이다. header에서는 memo를 사용해서 리렌더링이 안되지만, body와 footer 그리고 modal, modal background는 인풋값을 입력할 때마다 리렌더링된다. 만약에 이 인풋들을 useInput으로 관리하지 않고 useRef로 관리하게 된다면, 로그인 버튼을 눌렀을 때만 useRef.current.va..
특정 동작 시, useQuery하기 검색 원인 어떤 버튼을 클릭했을 때 method가 GET인 API를 useQuery로 실행하고 싶었다. 해결법 useState를 이용해서 useQuery의 옵션 중에서 enabled를 state값으로 주고, 어떤 동작을 했을 때 setState를 true로 바꾼다. 추가로, 이렇게 하면 enabled가 계속 true로 남아있기 때문에 GET 요청을 계속해서 하게 된다. 따라서 해당 요청이 성공했을 시에 state값을 다시 false로 바꾸는 코드까지 작성해주었다. // MessageText.tsx const MessageText = () => { const [fetchInvite, setFetchInvite] = useState(false); useAcceptInvite(link, fetchInvite,..

반응형