GROWTH LOG STORIES

함께 만든 성장을,
기록으로 연결합니다.

AI와 함께 배우고, 직접 만들고, 서로 나눈
그로스로그 멤버들의 생생한 성장 기록을 만나보세요.

성장 기록
5기+이어진 커뮤니티
HEALTHIO
PROJECT

사진 한 장으로 시작하는 건강 루틴, Health IO

대표 이야기 읽기

ALL STORIES

성장의 순간을
한곳에서 만나보세요.

프로젝트의 시작부터 모임에서 나눈 인사이트까지,
그로스로그가 함께 만든 기록을 모았습니다.
개의 성장 기록

성장일지

[GL 2기 3회차] 나누고, 모으고, 걸러내고 — React 컴포넌트와 props, reduce 연산자, includes 검색 필터 🌱

GROWTH LOG🌱 2026. 8. 9. 03:22

안녕하세요! 그로스로그 입니다!😊 🌱

화면을 조각으로 나누는 법, 흘러오는 값을 하나로 접는 법, 목록에서 원하는 것만 남기는 법. 2기 3회차 세 편입니다.

성장일지는 멤버들이 2주에 한 번씩 자신의 성장을 기록하는 활동이에요. 지난 기수의 성장일지를 다시 읽으면서, 그때 소개해드리지 못한 글을 하나씩 꺼내고 있습니다.

2기 3회차, 2024년 10월입니다. 이번 회차에는 데이터를 다루는 기본 동작 세 가지가 나란히 올라왔어요.

 

01

🧩 component, props

이주희 님

이런 내용이에요
React의 컴포넌트props를 정리한 학습 노트입니다. 함수형과 클래스형 두 방식을 코드로 나란히 보여줘요.
그리고 주의사항이 유난히 많습니다. 이름은 반드시 대문자로, return에는 괄호를, 컴포넌트 안에 컴포넌트를 정의하지 말 것, props는 순수 함수처럼 다룰 것.
마지막에는 하나의 컴포넌트를 세 개로 쪼갠 리팩터링 코드까지 붙였습니다.

React를 배우면 컴포넌트를 만드는 법은 금방 익힙니다. 함수 하나 쓰고 JSX를 반환하면 되니까요.

어려운 건 "언제 나누는가"입니다. 이 글은 나누는 법과 나눌 때 지켜야 할 것을 함께 정리했어요.

조금 더 들어가 보면

🔠 이름이 대문자여야 하는 이유

첫 번째 주의사항이 이겁니다.

이름은 항상 대문자
대문자로 작성하기, 그렇지 않으면 작동x

문법 규칙처럼 보이지만 사실은 구분을 위한 약속입니다.

JSX에서 <div>라고 쓰면 브라우저의 진짜 HTML 태그를 뜻하고, <Welcome>이라고 쓰면 내가 만든 컴포넌트를 뜻합니다. React가 이 둘을 어떻게 구별할까요. 첫 글자가 대문자인지 아닌지로 판단합니다.

그래서 function welcome()이라고 소문자로 만들고 <welcome />이라고 쓰면, React는 그걸 "welcome이라는 HTML 태그"로 해석합니다. 그런 태그는 없으니 아무것도 안 나오죠. 에러가 안 나고 조용히 빈 화면이 됩니다.

처음 React를 하면 이 실수로 한참 헤맵니다. 코드는 멀쩡해 보이고 콘솔도 깨끗한데 화면만 비어 있거든요. 주의사항 목록 맨 앞에 둘 만한 항목입니다.

🚫 컴포넌트 안에 컴포넌트를 만들면 안 되는 이유

두 번째 주의사항이 더 중요합니다. 글이 코드로 대비를 보여줘요.

export default function Gallery() {
  // 🔴 Never define a component inside another component!
  function Profile() {
    // ...
  }
}

// ✅ Declare components at the top level
function Profile() {
  // ...
}

그리고 이유를 한 줄로 적었습니다. "매우 느리고 버그를 일으킴."

왜 그럴까요. React는 화면을 다시 그릴 때 "이 컴포넌트가 아까 그 컴포넌트와 같은 것인가"를 확인합니다. 같으면 안에 들어 있던 상태를 그대로 유지하고, 다르면 통째로 새로 만들어요.

그런데 컴포넌트를 다른 컴포넌트 안에서 정의하면, 바깥 컴포넌트가 다시 그려질 때마다 안쪽 함수도 매번 새로 만들어집니다. 내용은 똑같은데 React가 보기엔 "다른 것"이에요.

결과가 고약합니다. 안쪽 컴포넌트가 통째로 버려지고 새로 만들어지니 거기 들어 있던 입력값이 사라지고, 스크롤 위치가 초기화되고, 애니메이션이 처음부터 다시 시작합니다. 그리고 이게 부모가 다시 그려질 때마다 반복되죠.

에러가 나는 게 아니라 이상하게 동작합니다. 그래서 원인을 찾기가 어렵습니다. "왜 입력하다 보면 글자가 지워지지" 같은 증상으로 나타나거든요.

📦 props는 아래로만 흐른다

props에 대한 설명에서 눈에 띄는 문장이 있습니다.

이름은 사용될 context가 아닌 컴포넌트 자체의 관점에서 짓기!

무슨 뜻이냐면, 버튼 컴포넌트에 색을 넘길 때 props.cancelButtonColor가 아니라 props.color라고 지으라는 겁니다.

컴포넌트는 자기가 어디에 쓰일지 몰라야 합니다. 취소 버튼에 쓰일지 확인 버튼에 쓰일지는 쓰는 쪽이 정할 일이에요. 이름에 쓰임새를 박아두면 다른 데 못 씁니다. 재사용하려고 만든 조각인데 재사용을 막는 셈이죠.

그리고 마지막 주의사항이 React의 핵심 규칙입니다.

주의 사항 순수 함수로 사용하기
자신의 입력 값을 변경하기 때문에 순수 함수 x

props를 받아서 고치면 안 된다는 뜻입니다. 같은 입력에는 항상 같은 출력이 나와야 해요.

이게 왜 규칙이 됐냐면, React는 화면을 언제 다시 그릴지 스스로 판단하기 때문입니다. 어떤 컴포넌트가 자기가 받은 값을 몰래 고쳐버리면, React가 "값이 안 바뀌었으니 다시 그릴 필요 없다"고 판단했는데 실제로는 바뀌어 있는 상황이 생깁니다. 화면과 데이터가 어긋나는 거죠.

📝 원문에서는 이렇게 나눕니다

글의 마지막에 리팩터링 예제가 있습니다. 댓글 하나를 보여주는 Comment 컴포넌트를 세 개로 쪼갰어요.

function Avatar(props) { ... }      // 프로필 사진만
function UserInfo(props) { ... }    // 사진 + 이름
function Comment(props) { ... }     // 사용자 정보 + 본문 + 날짜

한 덩어리였던 것이 Avatar → UserInfo → Comment 세 층으로 나뉘었습니다.

나누기 전에도 잘 동작했을 텐데 왜 나눌까요. 다시 쓸 자리가 생기기 때문입니다.

프로필 사진은 댓글에만 나오지 않습니다. 게시글 작성자에도, 알림 목록에도, 마이페이지에도 나와요. Avatar를 따로 빼두면 그 모든 곳에서 같은 것을 씁니다. 사진을 동그랗게 바꾸고 싶을 때 한 군데만 고치면 되고요.

그리고 날짜 형식을 함수로 뺀 것도 같은 발상입니다.

function formatDate(date) {
  return date.toLocaleDateString();
}

언제 나눌지에 대한 기준을 이 예제가 보여줍니다. 다른 데서도 쓸 것 같으면, 그리고 그 조각만 따로 설명할 수 있으면 나눌 때입니다.

큐레이터 노트

주의사항이 많아서 고른 글입니다.

학습 노트를 쓸 때 가장 쉬운 방식은 "이렇게 하면 됩니다"만 적는 겁니다. 문법을 따라 적고 예제를 붙이면 정리가 끝나요. 그런데 그렇게 쓴 노트는 나중에 다시 볼 일이 없습니다. 검색하면 나오는 내용이니까요.

이 글에는 하지 말아야 할 것이 함께 있습니다. 대문자로 안 쓰면 작동 안 하고, 컴포넌트 안에 컴포넌트를 만들면 느려지고, props를 고치면 순수 함수가 아니게 된다는 것.

막히는 지점을 미리 표시해둔 지도에 가깝습니다. 그리고 그런 항목은 대개 한 번 당해본 뒤에야 적게 되죠.

원문 읽으러 가기  ↗velog.io/@veryverysohappy/component-props
 

02

🧮 7장. 수학 및 결합 연산자 요약

남기준 님

남기준 님 원문에 실린 이미지
이런 내용이에요
RxJS의 수학·결합 연산자 네 가지를 정리한 글입니다. count·max·min·reduce요.
9,523자 분량인데, 연산자마다 원형 · 마블 다이어그램 · 실행 코드 · 결과 · 누적 과정 추적이 전부 붙어 있습니다.
특히 reduce초기값이 있을 때와 없을 때를 나눠서, 값이 어떻게 쌓여가는지를 한 단계씩 적어뒀어요.

RxJS는 시간에 따라 흘러오는 값들을 다루는 라이브러리입니다. 클릭 이벤트나 서버 응답처럼 언제 올지 모르는 것들을 하나의 흐름으로 보고 처리해요.

이 글은 그 흐름을 하나의 값으로 접는 연산자들을 다룹니다.

조금 더 들어가 보면

⏹️ complete가 있어야 결과가 나온다

글이 네 연산자의 공통 특징을 먼저 못 박습니다.

- 수학 개념을 기반으로 만들었다.
- 결합 속성이 있다
- 소스 옵저버블에서 complete 함수를 호출해야 결과를 next 함수로 발행할 수 있다.

세 번째가 핵심입니다. 흐름이 끝나야 답이 나옵니다.

당연해 보이지만 생각해보면 그럴 수밖에 없습니다. max를 구하려면 모든 값을 다 봐야 최댓값을 확정할 수 있어요. 아직 값이 더 올 수도 있는데 "지금까지 중 최대는 5"라고 발표할 수는 없죠. 다음에 10이 올 수도 있으니까요.

그런데 이게 실무에서 함정이 됩니다. 끝나지 않는 흐름에 이 연산자들을 쓰면 아무 결과도 안 나옵니다. 버튼 클릭 이벤트는 사용자가 페이지를 떠나기 전까지 끝나지 않아요. 거기에 reduce를 걸면 영원히 기다리게 됩니다.

에러도 안 납니다. 그냥 조용히 아무 일도 안 일어나요. 그래서 "왜 안 되지" 하고 한참 찾게 됩니다.

🔁 reduce와 scan의 차이

글이 reduce를 설명하며 scan과 비교합니다.

scan 연산자와의 차이점 - 매번 누적한 결과를 리턴하는 것이 아니다. 값을 계속 누적만 하고 발행하지 않다가 complete 함수를 호출할 때 한 번만 누적 결과를 발행한다.

같은 계산을 하는데 언제 알려주느냐가 다릅니다.

1, 2, 3, 4가 흘러올 때 scan은 1 → 3 → 6 → 10을 차례로 발행합니다. 중간 결과를 계속 보여줘요. reduce는 아무것도 안 내놓다가 마지막에 10 하나만 발행합니다.

쓰임이 갈립니다. 진행 상황을 화면에 보여줘야 하면 scan입니다. 장바구니에 물건을 담을 때마다 총액이 갱신되는 것처럼요. 최종 결과만 필요하면 reduce고요.

그리고 앞서 말한 함정과 이어집니다. scan은 끝나지 않는 흐름에도 쓸 수 있습니다. 매번 발행하니까요. reduce는 못 씁니다.

🌱 초기값이 있고 없고

이 글에서 가장 공들인 부분이 여기입니다. 초기값 유무를 나눠 실행 결과까지 보여줘요.

초기값이 없을 때 — 값이 하나뿐이면 누적자 함수를 아예 부르지 않습니다.

of(0).pipe(reduce((acc, cur) => acc + cur))
  .subscribe(result => console.log(`result: ${result}`));
// result: 0

글의 설명이 정확합니다. "2개 이상 값을 전달받지 못하므로 누적자 함수를 호출할 수 없다."

첫 값을 초기값으로 삼기 때문입니다. 비교하거나 더할 상대가 없으면 그냥 그 값을 내놓아요.

초기값이 있을 때 — 같은 코드에 1만 붙이면 결과가 달라집니다.

of(0).pipe(reduce((acc, cur) => acc + cur, 1))
// result: 1

값이 하나여도 누적자 함수가 한 번 돕니다. 1 + 0 = 1이죠.

그리고 값이 여러 개일 때 차이가 커집니다. range(1, 4)에 초기값 없이 하면 10, 초기값 1을 주면 11입니다. 초기값이 계산에 그대로 더해지니까요.

글이 누적 과정을 한 줄씩 적어둔 게 좋았습니다.

- 소스 옵저버블 1 -> 누적값 = 1 저장
- 소스 옵저버블 2 -> 누적자 함수 호출 (acc = 1, curr = 2), 1 + 2 = 3 계산 후, 누적값 = 3
- 소스 옵저버블 3 -> 누적자 함수 호출 (acc = 3, curr = 3), 3 + 3 = 6 계산 후, 누적값 = 6
- 소스 옵저버블 4 -> 누적자 함수 호출 (acc = 6, curr = 4), 6 + 4 = 10 계산 후, 누적값 = 10
- complete -> 누적값 10 발행 후 구독 완료

acccurr에 실제 숫자를 대입해 적었습니다. 누적자 함수를 처음 볼 때 헷갈리는 게 정확히 이 두 인자거든요. 어느 게 지금까지 쌓인 값이고 어느 게 새로 온 값인지요.

그리고 초기값이 왜 필요한지도 여기서 보입니다. 빈 흐름에 reduce를 걸면 초기값이 없을 때는 아무것도 발행하지 않지만, 있으면 초기값이 나옵니다. 합계를 구하는데 데이터가 없으면 0이 나와야지 아무것도 안 나오면 곤란하죠.

📝 원문에서는 이렇게 적습니다

연산자마다 원형(signature)을 먼저 붙여둔 게 눈에 띕니다.

reduce<T, R>(
  accumulator: (acc: R, value: T, index?: number) => R,
  seed?: R
): OperatorFunction<T, R>

타입스크립트 표기라 처음엔 어렵게 보이는데, 읽는 법을 알면 정보가 많습니다.

T는 들어오는 값의 타입, R은 나가는 값의 타입입니다. 둘이 다를 수 있다는 게 중요해요. 숫자들이 흘러와서 문자열 하나가 나올 수도 있습니다.

seed?의 물음표는 생략 가능하다는 표시입니다. 앞서 다룬 "초기값이 있을 때와 없을 때"가 여기 한 글자로 적혀 있는 거죠.

원형을 먼저 보는 습관은 라이브러리를 익힐 때 유용합니다. 예제만 따라 하면 예제와 똑같은 상황에서만 쓸 수 있는데, 원형을 읽으면 무엇을 바꿔도 되는지가 보이니까요.

큐레이터 노트

RxJS 연산자 정리를 회차마다 이어가고 계신 분입니다. 5장 변환 연산자, 6장 조합 연산자, 7장 수학·결합 연산자로요. 교재 한 권을 장 단위로 옮겨 적는 연재입니다.

이런 글은 "요약이라 볼 게 없다"고 넘기기 쉽습니다. 그런데 이 글에는 요약에 없는 게 셋 있습니다. 원형·실행 결과·누적 과정 추적이요.

특히 세 번째. acccurr에 실제 값을 넣어 단계별로 적는 건 자기가 이해했는지 확인하는 방법입니다. 머릿속으로 따라가면 어물쩍 넘어가는데, 숫자를 적어보면 안 맞는 지점이 드러나거든요.

9,523자 중 상당 부분이 그 확인 과정입니다. 읽는 사람에게도 도움이 되지만, 쓴 사람에게 가장 크게 남았을 부분이라고 생각합니다.

원문 읽으러 가기  ↗paekma09.tistory.com/11
 

03

🔍 includes() 메서드로 검색어 필터링 기능 만들어보기

정원석 님

이런 내용이에요
목록에서 검색어에 맞는 항목만 남기는 검색 필터를 바닐라 자바스크립트로 만들어본 기록입니다.
시작이 솔직해요. "이번에 코딩테스트에서 틀렸지만 사용해봤던 includes() 메서드로 검색 필터 기능을 만들어보고자 합니다."
HTML·CSS·JS를 순서대로 보여주고, 마지막에 전체 코드를 붙였습니다. 쓰인 메서드들(createElement·appendChild·toLowerCase·filter)도 정리해뒀어요.

라이브러리 없이 만듭니다. React도 jQuery도 없이 DOM을 직접 다뤄요.

조금 더 들어가 보면

🧹 다시 그리기 전에 지우기

핵심 코드는 짧습니다. 목록을 화면에 뿌리는 함수 하나와, 입력이 바뀔 때 걸러서 다시 뿌리는 이벤트 하나예요.

const rendedList = (todoItemList) => {
  const todoList = document.getElementById('todoList');
  todoList.innerHTML = '';   // 초기화 한번 시키고

  todoItemList.forEach((todo) => {
    const todoItem = document.createElement('div');
    todoItem.className = 'todo-list';
    todoItem.textContent = todo.content;
    todoList.appendChild(todoItem);
  });
};

innerHTML = '' 한 줄에 주석이 붙어 있습니다. "초기화 한번 시키고."

이 줄이 없으면 어떻게 될까요. 검색어를 칠 때마다 결과가 기존 목록 아래에 계속 쌓입니다. 지우고 그리는 게 아니라 계속 붙이니까요.

직접 DOM을 다룰 때 반드시 만나는 지점입니다. React 같은 라이브러리를 쓰면 이 일을 대신 해주는데, 없으면 "이전 상태를 치우는 것"까지 내 몫입니다.

그리고 이 방식에는 대가가 있습니다. 매번 전부 지우고 전부 다시 만듭니다. 항목이 네 개면 아무 문제 없지만 수천 개면 느려져요. 입력할 때마다 수천 개의 요소를 지우고 다시 만드는 셈이니까요.

React가 하는 일이 정확히 이 문제를 푸는 겁니다. 바뀐 것만 골라서 고치는 것이요. 직접 만들어보면 라이브러리가 뭘 대신해주는지가 보입니다.

🔡 대소문자를 맞춰놓고 비교하기

필터 부분이 한 줄입니다.

const inputValue = searchInput.value.toLowerCase();
const filterTodos = todos.filter((todo) =>
  todo.content.toLowerCase().includes(inputValue)
);

글이 toLowerCase()를 쓴 이유를 설명합니다.

검색을 할 때 대소문자를 신경 안쓰고 검색을 할 수 있게 하기 위해서 입니다.

양쪽 다 소문자로 바꾼 게 포인트입니다. 한쪽만 바꾸면 소용이 없어요. 검색어를 소문자로 만들어도 원본이 Reactreact로는 안 걸립니다.

그래서 비교하기 전에 양쪽을 같은 형태로 맞추는 것이 검색 기능의 기본이 됩니다. 실무에서는 여기에 공백 제거(trim)가 더 붙고, 한글이면 자모 분리 같은 처리까지 가기도 하죠.

filterincludes의 역할 분담도 깔끔합니다. filter는 목록을 돌면서 조건에 맞는 것만 남기고, includes는 문자열 안에 검색어가 들어 있는지 판정합니다. 각자 하나씩만 해요.

filter가 새 배열을 돌려준다는 점도 중요합니다. 원본 todos는 그대로 남습니다. 그래서 검색어를 지우면 전체 목록이 다시 나올 수 있어요. 만약 원본을 직접 걸러버렸다면 한 번 검색한 뒤에는 돌아갈 수 없습니다.

⌨️ input 이벤트를 고른 것

이벤트 종류도 눈여겨볼 만합니다.

searchInput.addEventListener('input', () => { ... });

change가 아니라 input입니다. change는 입력을 마치고 포커스가 빠져야 발생하고, input은 글자 하나 칠 때마다 발생해요.

검색 필터는 치는 즉시 결과가 줄어들어야 하니 input이 맞습니다. 이게 요즘 흔히 보는 실시간 검색의 동작이고요.

다만 실무에서는 여기에 하나가 더 붙습니다. 디바운스라고, 입력이 멈춘 뒤 잠깐 기다렸다 실행하는 장치예요. 지금처럼 화면 안의 배열만 거를 때는 필요 없지만, 검색할 때마다 서버에 요청을 보낸다면 글자 수만큼 요청이 나가버리거든요.

📝 원문에서는 이렇게 마무리합니다

쓰인 메서드를 스스로 정리하며 끝냅니다.

여기서 보이는 메서드들은 createElement(), appendChild(), toLowerCase(), filter() 정도가 있겠네요.
createElement()메서드와 toLowerCase()메서드는 간단한 메서드라 정리를 안할겁니다.

만들면서 쓴 도구를 되짚고, 그중 뭘 더 볼지 골랐습니다. 다 정리하지 않고 간단한 건 넘긴다고 밝힌 것도 좋고요.

시작 문장도 다시 볼 만합니다.

이번에 코딩테스트에서 틀렸지만 사용해봤던 includes()메서드로

틀린 문제에서 쓴 메서드를 가져와 다른 걸 만들어본 것입니다. 틀린 채로 넘어가지 않고, 시험 밖에서 한 번 더 써본 거예요.

큐레이터 노트

라이브러리 없이 만들어본 기록이라 뽑았습니다.

지금은 검색 필터를 만들 때 React를 쓰는 게 자연스럽습니다. 상태 하나 만들고 조건 걸면 끝이니까요. 그런데 그렇게만 하면 화면이 어떻게 갱신되는지는 영영 안 보입니다.

이 글은 그 과정을 직접 씁니다. 지우고, 만들고, 붙이고. 그러면서 "지우는 걸 잊으면 쌓인다"는 것도 몸으로 알게 되죠. 4회차 큐레이션에서 다룰 이야기와도 이어지는데, 편해지는 도구를 쓰기 전에 그게 뭘 대신해주는지 한 번 보는 것은 값이 있습니다.

그리고 "코딩테스트에서 틀렸지만"으로 시작한 점. 틀린 것을 감추지 않고 출발점으로 삼았습니다. 시험이 끝나면 대개 그 문제를 다시 보지 않는데, 여기서는 거기서 만난 메서드를 가지고 작은 것을 하나 만들었어요.

원문 읽으러 가기  ↗coding-studing.tistory.com/16

💡 세 편을 겹쳐 읽으며

세 글이 쓰는 도구가 다릅니다. React, RxJS, 그리고 아무것도 안 쓴 바닐라 자바스크립트예요.

그런데 셋을 나란히 놓으면 데이터를 다루는 기본 동작 세 가지가 됩니다.

  하는 일
나누기 하나를 여러 조각으로 이주희 — 컴포넌트와 props
모으기 여러 값을 하나로 남기준 — reduce·count·max·min
걸러내기 조건에 맞는 것만 남기기 정원석 — filter와 includes

프로그램이 하는 일은 결국 이 세 가지의 조합입니다. 큰 것을 다룰 수 있는 크기로 쪼개고, 흩어진 것을 하나로 합치고, 필요한 것만 골라내는 것이요.

세 글이 함께 지키는 원칙

재밌는 건 세 글 모두 "원본을 건드리지 않는다"는 원칙을 짚는다는 점입니다.

이주희 님은 props를 순수 함수처럼 다루라고 적었습니다. 받은 값을 고치지 말라는 것이죠.

남기준 님의 reduce는 흘러온 값들을 바꾸지 않습니다. 새로운 누적값을 따로 만들어 발행해요.

정원석 님의 filter도 원본 배열을 그대로 두고 새 배열을 돌려줍니다.

이게 왜 공통일까요. 원본을 고치면 되돌릴 수 없기 때문입니다.

검색어를 지웠을 때 전체 목록이 다시 나오려면 원본이 남아 있어야 합니다. 화면을 다시 그릴지 판단하려면 이전 값과 지금 값을 비교할 수 있어야 하고요.

바꾸지 않고 새로 만드는 방식이 번거로워 보여도, 그 덕분에 되돌아갈 자리가 생깁니다.

셋 다 직접 돌려봤다

그리고 세 편에는 확인한 흔적이 있습니다.

남기준 님은 누적 과정에 숫자를 하나씩 대입해 적었습니다. 정원석 님은 코드를 돌려 실제 화면을 만들었고요. 이주희 님은 한 컴포넌트를 세 개로 쪼개는 코드를 함께 올렸습니다.

읽고 이해한 것과 돌려보고 확인한 것은 남는 게 다릅니다.

이번 회차에서 가져갈 것

1. 컴포넌트를 다른 컴포넌트 안에서 정의하지 않기.

에러가 안 나서 더 위험합니다. 부모가 다시 그려질 때마다 안쪽이 통째로 새로 만들어져서, 입력값이 사라지거나 스크롤이 튀는 증상으로 나타납니다. 파일 맨 바깥에 선언하는 것이 원칙입니다.

2. 끝나지 않는 흐름에 reduce를 걸지 않기.

max·min·count·reduce는 흐름이 완료돼야 결과를 냅니다. 클릭 이벤트처럼 끝나지 않는 것에 걸면 에러 없이 조용히 아무 일도 안 일어납니다. 중간 결과가 필요하면 scan을 쓰세요.

3. 비교 전에 양쪽 형태를 맞추기.

검색어와 원본 둘 다 소문자로 바꿔야 합니다. 한쪽만 바꾸면 소용이 없어요. 공백 제거까지 함께 해두면 "왜 검색이 안 되지"의 절반은 사라집니다.

4. 원본을 고치지 말고 새로 만들기.

filter가 새 배열을 주는 덕분에 검색어를 지우면 전체가 돌아옵니다. props를 고치지 않는 덕분에 React가 화면 갱신을 판단할 수 있고요. 되돌릴 자리를 남겨두는 것이 이 원칙의 이유입니다.

5. 라이브러리가 대신해주는 일을 한 번은 직접 해보기.

목록을 지우고 다시 그리는 코드를 직접 써보면, React가 왜 "바뀐 것만 고치는" 방식을 만들었는지가 이해됩니다. 편의 기능은 그게 없을 때의 불편을 겪어봐야 제대로 쓸 수 있습니다.


2기 3회차는 2024년 10월 중순이었습니다. 학기가 한창이라 각자 진도가 붙기 시작할 때예요.

세 분이 서로 다른 도구를 붙들고 있었습니다. React, RxJS, 그리고 아무것도 안 쓴 바닐라 자바스크립트로요.

그런데 결과적으로 같은 이야기의 다른 면을 적었습니다. 2주에 한 번 같은 자리에 글이 모이니까 보이는 우연입니다.

좋은 글 남겨주신 이주희 님, 남기준 님, 정원석 님께 감사드립니다.

그리고 2기를 함께 채워주신 모든 멤버분들께도요! 😊

다음 큐레이션으로 다시 찾아오겠습니다! 🌱

- 에디터 · 성장일지 큐레이터 -


※ 본 큐레이션은 각 저자가 공개한 글을 소개하는 것이며, 모든 원문의 저작권은 저자에게 있습니다. 저자 본인의 요청이 있을 경우 즉시 수정 또는 삭제합니다.

WRITE YOUR GROWTH

오늘의 배움을
내일의 성장으로.

기록은 나를 돌아보게 하고, 공유는 우리를 연결합니다.
당신의 다음 성장 이야기도 그로스로그에서 시작해보세요.

커뮤니티 둘러보기