[React] 자식 컴포넌트의 데이터를 부모 컴포넌트로 전달하기 (feat. Todo List App) / useState, useEffect, useRef
🚀 들어가며
리액트로 Todo List App을 만들던 중 막히는 부분이 생겼다. 각 기능을 컴포넌트 단위로 분리하여 구현하고 있었는데 자식 컴포넌트가 가지는 데이터를 부모 컴포넌트에 전달하는 것과, 그 데이터를 부모 컴포넌트가 다른 하위 컴포넌트로 뿌려주고 자동으로 렌더링되도록 구현하고 싶었는데 뜻대로 되지 않았다. 어찌하다가 막무가내로 구현은 했으나 코드가 깔끔하지 않았다. 결국 코드를 엎고 다시 처음부터 천천히 해보게 되었고 구현에 성공했다. 이번 기회로 알게된 내용을 포스팅을 통해 정리하면 많은 도움이 될 것 같아서 글을 쓰게 되었다.
✅ 컴포넌트 구성
설명을 위한 컴포넌트는 아래와 같이 구성했다. App.js 안에 TodoForm 컴포넌트와 TodoList 컴포넌트를 구성했고 TodoForm은 Todo를 입력을 받아 저장하고, 저장된 Todo들을 TodoList 컴포넌트에 렌더링하는 구조이다.
✅ 레이아웃 구성
컴포넌트 구성에 의하여 아래의 레이아웃 구성을 가진다.(CSS는 추가하지 않았다.. ㅎㅎ)
✅ 자식 컴포넌트의 데이터를 부모 컴포넌트에 전달하기
부모 컴포넌트의 데이터를 자식 컴포넌트에 전달하는 것은 간단하다. props로 전달하고 자식 컴포넌트에서 useState 훅을 사용하여 초기화해주면 된다. 그렇다면 자식 컴포넌트의 데이터를 부모 컴포넌트의 데이터에 전달하려면 어떻게 해야할까?
▪︎ App.js
그것도 역시 생각보다 간단하다. 나처럼 자식 컴포넌트(TodoForm)의 데이터를 부모 컴포넌트(App)에서 받아서 다시 다른 자식 컴포넌트(TodoList)에 전달하려면 부모 컴포넌트의 useState 훅의 변수를 자식 컴포넌트의 props에 전달해주면 된다.
위의 코드와 같이 자식 컴포넌트들에 부모 컴포넌트의 useState 훅의 변수를 자식 컴포넌트의 props에 전달하면 된다.
▪︎ TodoForm.js
전달한 부모 컴포넌트의 useState 훅의 변수를 TodoForm 컴포넌트에서 어떻게 활용하는지 살펴보자.
- line 32 : input 태그의 onChange 이벤트가 발생할 때 onChangeCallback 핸들러가 실행된다.
- line 13 : TodoForm 컴포넌트의 useState 훅의 변수인 setTodo 함수를 호출하여 input 태그의 value 값으로 state를 갱신한다.
- line 28 : form 태그의 onSubmit 이벤트가 발생할 때 onSubmitCallback 핸들러가 실행된다.
- line 18 : App 컴포넌트에서 전달받은 todoList(App.js의 state)에 TodoForm 컴포넌트의 todo(TodoForm.js의 state)를 concat 메서드를 통해 합친다.
- line 22 : App 컴포넌트에서 전달받은 setTodoList의 인자로 line 18에서 합친 새로운 todoList(App.js의 state)를 전달함으로써 App 컴포넌트의 state가 변경된다.
▪︎ TodoList.js
TodoForm 컴포넌트에서 App 컴포넌트의 state를 변경해주었다. 이제 변경된 App 컴포넌트의 state를 기반으로 TodoList 컴포넌트를 다시 렌더링한다. 한번 살펴보자.
- line 4 : App 컴포넌트에서 전달받은 todoList(App.js의 state)를 활용하여 리스트를 그린다.
- 현재 setTodoList는 사용되지 않고 있다.
이렇게 부모 컴포넌트의 useState 훅의 변수를 자식 컴포넌트의 props로 전달해주고, 자식 컴포넌트의 특정 이벤트 핸들러에 부모 컴포넌트의 useState 훅의 상태 변경 변수를 호출하면 된다.
✅ useRef
위의 기능을 구현하다가 useRef 훅이라는 것을 알게 되었고 궁금해져서 useRef 훅을 직접 사용해보았다. useRef와 useState의 차이점은 다음과 같다.
- useState : state의 변화 -> 렌더링 O -> 컴포넌트 내부 변수들 초기화
- useRef : ref의 변화 -> 렌더링 X -> 변수들 값 유지됨
또한 useRef 훅을 활용하여 DOM 요소에 접근할 수 있는데, 이를 활용하여 input 태그가 있는 페이지에 접근했을 때 자동으로 input 박스에 포커싱되도록 구현할 수 있다.
- line 6 : Ref 객체를 생성한다.
- line 33 : 생성한 Ref 객체를 선택하고 싶은 DOM 요소에 ref 값으로 설정한다. 이러면 Ref 객체의 .current 값은 해당 DOM 요소를 가리키게 된다.
- line 8 : useEffect 훅을 활용하여 초기 렌더링 시 선택한 DOM 요소가 focus되어 있도록 처리한다.
- link 24 : 작성한 todo를 저장하는 버튼을 클릭했을 때도 선택한 DOM 요소가 focus되어 있도록 처리한다.
위와 같이 useRef 훅을 사용하면 번거롭게 input 박스를 마우스로 클릭하지 않아도 자동으로 input 박스가 선택되어 있기 때문에 사용자에게 보다 쾌적한 환경을 제공할 수 있다.
🛸 마치며
리액트로 Todo List App을 만들면서 생긴 문제들을 해결하면서 리액트에 좀 더 가까워질 수 있었다. 또, 바닐라 자바스크립트와는 또 다른 재미가 있다는 것을 느낄 수 있었다. useState 훅과 useEffect 훅 이외에도 useRef 훅을 사용하며 쾌적한 사용자 경험을 제공하기 위해 한 발자국 더 나아갔다는 생각이 들어 뿌듯하다.