Curt Poem

프론트 엔드 공부와 지식 나눔을 위한 블로그

개발/React와 프레임워크들 16

리액트의 context을 구현해보면서 context 최적화에 대해 알아보자

리액트의 context의 API는 Prop Drilling을 해결하기 위한 한 가지 방법으로 상위 컴포넌트에서 관리하는 상태를 자식 컴포넌트가 props을 받지 않고 해당 상태를 사용할 수 있게 만들어줍니다. 먼저 간단한 사용법을 알아보겠습니다.Context API의 사용방법context 만들기context api를 사용하기 위해 가장 먼저해야할 일은 context를 만드는 일입니다. 깊이 중첩되어 있는 자식에게 전달할 상태를 정하는 작업입니다.const MyContext = createContext({ count: 0, increase: () => { console.log("provide없음"); },});context의 생성은 위와 같이 아주 간단합니다. createContext함수에 전달..

리스트 렌더링과 컴포넌트 초기화에 활용되는 key prop.

리액트에서 리스트를 이용해 컴포넌트를 렌더링하도록 하면 key prop을 붙이는 것을 권장하고 있습니다. 만약 key를 사용하지 않으면 다음과 같은 에러를 콘솔에 출력하고 내부적으로는 인덱스를 key로 사용하게 됩니다.리액트에서 Key는 어떤 역할을 하길래 리스트의 렌더링에 필수적으로 사용하여야 할까요?리스트 항목을 순서대로 유지공식 문서에 따르면 리스트에서 key prop의 역할은 리스트 항목을 순서대로 유지하기 위해서입니다. key를 사용한다면 리스트의 각 요소를 식별하여 올바른 순서를 유지할 수 있도록 만듭니다. 그런데 리스트의 항목을 순서대로 유지한다는 것은 무슨 말일까요? 리스트라는 자료 구조 자체에서 이미 순서를 유지하기 때문에 key를 사용하지 않아도 순서는 유지되는 데 말입니다.key의 작..

React에서 화면과 로직의 분리 도전기(with. context API)

지난 번 플러터를 사용하여 프로젝트를 진행하였을 때, MVVM패턴을 통해 화면과 로직이 분리되어 수정이 편하고 비즈니스 로직 또는 서버의 변화에 대한 대처가 용이하다고 느꼈습니다. 이번에는 화면과 로직을 분리하는 방식을 리액트에서도 적용하고 싶었지만 몇 가지 문제가 있었고 이를 어떻게 해결할지에 대한 고민을 정리한 글입니다. 사실 커스텀 훅을 사용하는 것이 더 나은 방법이지만 로직을 리액트에서 완전히 분리하여 독립적으로 사용하는 방법을 생각해보는 내용입니다. 즉 리액트로 작성되어 있지 않은 로직을 리액트 컴포넌트에서 그대로 사용할 수 있는 방법입니다.일단 코드만이라도 나누어보자간단한 이해를 위해 실제 분리가 아닌 코드를 나눌 뿐이므로 바쁘시다면 생략하고 실제로 화면과 로직 분리하기로 바로 넘어가주세요.로..

Next JS 앱 라우터 간단 정리

Next js지난번에 SSR에 대해 포스팅한적이 있습니다. 아주 간단하게 요약하자면 웹 페이지 방문자가 볼 컨텐츠를 서버에서 (어느정도는)그린 다음에 클라이언트에 전송해 주는 방식입니다. SSR을 사용하기 위해서는 프론트 엔드 서버가 필요하고 해당 서버를 구축하기 위한 방법 중 하나가 바로 Next js입니다. Next는 React를 기반으로 하는 SPA 프레임워크로 오늘은 단순 React 프로젝트와의 가장 큰 차이점 중 하나인 앱 라우터를 설명해보고자 합니다.라우팅Next.js의 앱 라우터(App Router)는 Next.js 13에서 도입된 기능입니다. 이전까지는 페이지 라우터만을 사용할 수 있었습니다. Next.js 앱 라우터는 웹 애플리케이션의 URL 구조를 정의하고 사용자 요청에 따라 적절한 페..

useReducer로 복잡한 State를 더 쉽게 관리하기

리액트로 개발을 진행하다보면 하나의 컴포넌트에서 여러 개의 상태(state)를 사용해야 될 때가 있습니다. 상태가 많아지는 것 자체는 큰 문제가 되지 않을 수도 있지만 상태가 많을 경우 여러 방식으로 상태가 변화할 수 있기 때문에 상태 관리가 복잡해 질 수있습니다. 리액트에서는 이 문제를 해결하기 위해 Reducer를 사용할 수 있습니다.예시 코드만약 목록들을 생성, 수정, 삭제하는 기능을 가진 컴포넌트를 만들어야 한다고 가정해봅시다. 그러면 해당 요구사항을 충족하기 위해 다음과 같은 컴포넌트를 만들 수 있습니다.import { useState } from 'react';import AddElement from "./AddElement"import List from "./List"export defaul..

트러블 슈팅: React Native의 FormData는 웹과 (조금)다릅니다! (feat. 서버가 FormData의 key와 value를 구분하는 법)

리액트 네이티브를 사용한 개발을 진행하던 중 한 가지 문제가 생겼습니다. FormData를 통해 백엔드에 데이터를 보내주었는데 백엔드 측에서 이를 읽지 못하였습니다. 분명 키와 값 쌍을 정해주었는데 해당 키를 null로 조회하였습니다. 백엔드 측의 코드도, 프론트엔드 측의 코드도 아무런 문제가 없어 보였는데 말이죠.FormData는 무엇인가?FormData는 form 필드와 그 데잍터를 나타내는 키-값 쌍을 쉽게 생성할 수 있는 인터페이스입니다. 이름에서도 유추할 수 있듯이 html의 form을 구성하는 데이터를 쉽게 구성할 수 있도록 도와주는 객체입니다. HTML의 경우 다음과 같은 코드를 작성하면 해당 폼 요소가 가진 필드 전체가 자동으로 FormData로 구성이 됩니다. FormData의 인자는 f..

FSD 아키텍처를 참고하여 SSAFY 프로젝트(EXPO, RN)에 맞게 바꿔서 써보자!

만약 FSD 아키텍처가 궁금하다면 이 글을 참조하세요FSD 아키텍처 OOP의 장점을 프론트엔드로! FSD 아키텍처, OOP의 장점을 프론트엔드로!기존의 기능 분할 설계(Feature-Sliced Design, FSD) 아키텍처 FSD는 다형성(polymorphism), 캡슐화(encapsulation), 상속(inheritance) 및 추상화(abstraction) 와 같은 개념을 프런트엔드에 적용하는 데 도움을 줍니다.curt-poem.tistory.com 저는 싸피에서 프로젝트를 진행하면서 불편한 점을 하나 느꼈습니다. 바로 프로젝트의 폴더 구조였습니다. 기존에 진행하였던 프로젝트에서는 강의에서 들었던 방식과 유사한 구조를 만들었습니다. assets, components, page, store, ut..

미니 트러블 슈팅: 스마트폰에서 EXPO GO 앱으로 EXPO 프로젝트 연결안되는 문제 - Something went wrong

expo는 개발중인 스마트폰 어플리케이션을 아주 쉽게 스마트폰에서 실험할 수 있는 환경을 제공합니다. 프로젝트 폴더에서 npm start 명령어를 입력하면 즉시 개발 서버가 실행되면서 스마트폰에서 실행할 수 있도록 QR 코드가 나타납니다. 마켓에서 EXPO GO 어플리케이션을 다운받아 실행하여 QR코드를 찍으면 바로 개발중인 어플리케이션을 스마트폰을 비롯한 안드로이드/IOS 기기에서 사용가능하다는 장점이 있습니다. 저같은 경우 SSAFY에서 지급받은 노트북을 사용할 때는 android 애뮬레이터를 이용하였지만 개인 노트북에서는 애뮬레이터와 함께 사용하면 심하게 버벅였습니다. 그래서 EXPO GO 앱을 이용한 테스트가 절실한 상황이었습니다...ㅠ 문제그런데 남들은 다 된다는 EXPO GO 어플리케이션이 저..

리액트, 가장 흔한 실수

SSAFY에서 프로젝트를 시작하면서 몇몇 질문을 받았습니다. 특히, 리액트에서 의도한 동작이 수행되지 않는 경우에 대한 질문이 많았습니다. 그런 질문의 대부분이 useState 훅에 대한 이해가 부족하였기 때문에 벌어진 일이었습니다. 그래서 이 문제가 발생하는 원인을 설명하고 간단한 해결책을 알려드리겠습니다.useState의 set 함수는 상태를 즉시 변경하지 않습니다.useState로 만든 상태 변수를 읽을 때, set 함수를 통해 상태를 업데이트 하였지만 최신값을 가지고 있지 않기 때문에 문제가 발생합니다. 다음 코드를 보시죠.import { useState } from "react";function App() { const [count, setCount] = useState(0); const [..

Side Effect(부수효과)를 처리하기 위해 useEffect를 사용하는 경우와 useEffect를 꼭 사용하지 않아도 되는 상황

useEffect 훅의 목적 중 하나는 부수효과를 안전하게 처리하는 것입니다. 부수효과란 앱이 의도한 대로 동작하기 위해 실행되어야 하지만 현재의 컴포넌트 렌더링 과정에 직접적인 영향을 미치지는 않는 작업입니다. 이러한 작업들은 꼭 실행되어야하는 작업이지만 현 컴포넌트 렌더링 과정에 직접적이고 즉각적인 영향을 미치지 않는 작업들이죠. 즉각적인 변화를 주지 않고 뒤늦게 영향을 주기 때문에 무한 루프 같은 문제점이 발생할 수 있습니다. useEffect로 부수효과 안전하게 처리하기 HTTP 요청에서의 부수효과 일반적으로 이러한 부수 효과는 외부 서버에서 데이터를 불러오는 작업 등 비동기 함수를 실행하는 상황에서 쉽게 볼 수 있습니다. 다음 코드를 보시죠. import { useState, useEffect ..

React 트러블 슈팅: Request canceled

axios 요청의 try-catch문에서 catch (error) {console.log(error)}로 인해 콘솔창에 나온 메세지였습니다. canceled라는 에러가 발생하였는데 요청을 취소하는 로직을 추가한 상태도 아니었습니다. Tanstack ReactQuery 라이브러리를 사용하고 있었기에 Tanstack에서 뭔가 이상을 감지하고 취소하였을 거라 생각도 해보았지만 요청이 취소될 이유가 전혀 없어 보였습니다. error의 signal 항목을 살펴보니 다음과 같이 reason이라는 항목이 있어 확인해보았습니다. code: 20에 message: signal is aborted without reason"라는 것을 확인할 수 있었습니다. 아무런 정보를 얻지못했죠. 그래서 다른 곳에 원인이 있을 것이라고..

Prop으로 컴포넌트에 데이터 전달하기(+ 특별한 'children' props)

컴포넌트를 사용하는 것 여러 이점 중 하나는 바로 재사용이 가능하다는 점입니다. 만약 페이지에 내용은 다르지만 같은 구조와 기능을 가진 것을 여러 번 표시해야한다면 컴포넌트를 사용하는 것이 하나의 해결책이 됩니다. 실제로는 단 한 번만 사용하는 컴포넌트를 만들 때도 많지만, 이론적으로 컴포넌트들은 얼마든지 재사용이 가능합니다. 매개 변수(Parameter)를 받아 같은 계산을 실행하는 함수처럼 컴포넌트는 데이터를 받아 같은 과정을 거쳐 결과를 보여줍니다. 여기서 우리가 넘겨주는 데이터가 바로 Prop(Property, 속성)입니다. Prop Prop은 '속성'이라는 의미를 가지며 데이터를 컴포넌트로 전달하고 그 컴포넌트에서 받은 데이터를 사용할 수 있게 합니다. 컴포넌트를 여러 번 재사용하기 위해 속성을..

React에서 불변성은 왜 중요할까요?

우리가 데이터를 변경하기 위해서 기존의 데이터를 직접 수정할 수도 있고, 기존의 데이터를 복사하여 새롭게 만들어진 데이터를 수정하는 방법을 사용할 수도 있습니다. 전자의 경우 인덱스를 통해 접근하여 수정하거나 splice 메서드를 이용할 수 있고 후자의 경우는 map 메서드를 이용할 수 있습니다. 리액트에서는 map, concat, filter 등의 새로운 배열을 반환하는 방법(불변성을 유지하는 방법)을 권장하고 있습니다. 왜 그럴까요? 🗒️: 만약 원시값과 참조값에 대해 잘 알지 못하시면 이해가 어려울 수도 있습니다. 불변성을 사용하는 것의 이점 사이드 이펙트를 방지할 수 있습니다. 앞선 글에서 리액트는 상태의 변경을 즉시 처리하지 않고 예약해두었다가 리렌더링한다고 하였습니다. 그래서 리액트는 상태가 ..

리액트가 리렌더링되는 시점과 useEffect로 실제 시점 살펴보기

상태와 리렌더링리액트의 컴포넌트는 상태가 변하면 해당 컴포넌트를 재평가(함수형 컴포넌트라면 함수를 재실행, 클래스형 컴포넌트라면 다시 인스턴스화)하여 새로운 내용이 반영하여 새로 UI를 그립니다. 이러한 행위를 리렌더링(re-rendering)이라고 합니다. 결국 리액트는 최초 렌더링 - 상태의 변화 - 리렌더링(렌더링)의 단계를 거치며 새로운 컨텐츠를 화면에 표시하는 것이죠. 하지만 이렇게만 생각하면 조금 헷갈릴 수 있습니다. 혼란을 줄이기 위해 조금 더 상세한 단계를 알아봅시다.먼저 리액트의 컴포넌트가 최초로 렌더링됩니다. 그리고 상태변화 요청이 오기 전까지는 계속 대기하죠. 그러다가 사용자가 버튼을 누르는 등의 행동을 통해 상태를 변화(set함수를 호출하는 로직을 실행)시키면 리액트는 해당 요청을 ..

리액트 useState의 사용법과 주의점(feat. HOOK 사용 규칙)

앞선 글에서 리액트는 SPA를 만드는 라이브러리라고 했습니다. SPA는 페이지 이동없이 동적인 콘텐츠를 표시할 수 있는 어플리케이션입니다. SPA를 구현하기 위해서는 여러 콘텐츠를 사용자와의 상호작용에 따라 보여줄 수 있어야 하죠. 리액트는 훅이라고 불리는 것으로 동적인 값을 관리할 수 있습니다. '훅'이라는 용어는 함수형 컴포넌트 내에서 특정한 리액트 기능에 "연결(hook into)"하거나 액세스할 수 있는 개념을 나타냅니다. 리액트의 수 많은 'Hook' 중에서 가장 기초가 되는 Hook인 userState에 대해서 알아보겠습니다. HOOK의 규칙 useState에 대해 자세히 알아보기 전에 모든 리액트 Hook들이 가지는 공통적인 규칙 먼저 알아보겠습니다. 리액트의 모든 Hook들은 컴포넌트의 최..

리액트의 특징 그리고 가상 돔(Virtual DOM)

리액트 리액트(React)는 페이스북에서 개발된 JavaScript 라이브러리로, 사용자 인터페이스를 만들기 위한 것입니다. 주로 SPA(Single Page Application, 단일 페이지 애플리케이션)을 구축하는 데 사용되며, 재사용 가능한 UI 컴포넌트를 효과적으로 관리할 수 있도록 도와줍니다. 또한 리액트는 가상 DOM(Virtual DOM)을 사용하여 성능을 최적화하고, 데이터가 변경될 때 효율적으로 업데이트를 처리합니다. SPA와 가상 DOM 및 DOM에 관해서 간략하게 소개드리자면, SPA는 페이지의 이동없이 동적으로 페이지의 콘텐츠를 업데이트하는 웹 애플리케이션입니다. 그리고 가상 DOM은 실제 DOM을 효율적으로 업데이트하여 성능을 향상시키는 기술입니다. Vue.js와 같은 다른 자바..