이번 장에서는 이전 2장의 Props를 이용해 이벤트를 관리하는 것부터 정리할 것이다. 시작해 보자.
이벤트 (Event)
Vanilla JS에서 Script로서 event 객체 넘겨받는 그 이벤트랑 같은 이벤트다. 그래서 영어로도 언급했다.
사용법
우선 2장과 비슷한 코드로 계속해서 실습 예시를 보자.
2장과 같은 코드에, topics
에서 text
key를 삭제하고, <Header>
태그를 추가했다. (당연히 Header 컴포넌트도 작성했다.)
그 결과 이런 뷰가 나타나게 된다.
우리는 여기서 <Header>
을 클릭할 경우 '안녕!!!!!'이라는 문구가, 아래 <li>
를 클릭할 경우 각 <li>
의 key
가 alert으로 표시되도록 하고 싶다.
처음으로 할 것은, App
함수 내 타깃 태그들에 props
로 넘길 함수들을 생성해 줘야 한다. 이때는 직접 행위를 통해 실행되어야 할 feature을 작성해 준다.
각 타깃 태그들에 onChangeMode
라는 이름으로 화살표 함수를 작성해 주었다. Header
의 경우 단순 사전 지정된 String만 표시하므로 상관없지만, Nav
의 경우 어떤 li
를 선택하는지에 따라 다른 key
를 표시해야 하므로 파라미터로 key
를 작성해 주었다.
이제 각 컴포넌트 내에 event 객체를 받아 처리하는 로직을 구현할 차례이다. 각 컴포넌트 안에는, App 내의 태그들의 직접 행위를 돕는 사전 과정을 작성해 준다.
우선 Header
컴포넌트부터 보자.
6번 줄을 수정했고 7, 8번 줄을 새로 작성했다. 6번 줄에는 onClick
속성(React에서는 CamelCase 사용)을 추가해 event
객체를 파라미터로 넘겼다. 화살표 함수 내에는 페이지가 새로고침 되지 않도록 event.preventDefault();
구문을 작성해 주었고, 위에서 작성해 props
파라미터로 넘어온 Header
태그의 속성인 onChangeMode
함수도 실행시켜 주었다.
다음으로는 비슷하지만 조금 더 어려운 Nav
컴포넌트를 보자.
18번 줄이 수정되었고, 19, 20번 줄이 새로 추가되었다. 18번 줄에는 a
태그에서 발생한 event
객체의 target.id
값을 불러와 20번 줄의 props.onChangeMode
에 파라미터로 전달하기 위해 id
속성을 추가해 주었다. 나머지는 20번 줄의 event.target.id
를 파라미터로 전달한다는 것 외에는 모두 같다.
이와 같이 코드를 작성해주면 요구 기능사항대로 잘 작동한다.
이렇게 React의 이벤트에 대해서도 잘 알아보았다.
Props를 이용해 컴포넌트의 사용 대상과 컴포넌트 자체를 자유롭게 움직이며 데이터를 전달하고, Event를 이용해 타깃의 정보를 불러와 Props를 자유로이 사용할 수 있게 되었다.
그렇다면, props와 비슷하게 데이터를 전달하면서 컴포넌트 내에서만 사용하는 기능은 없을까?
State (상태)
State는 React에서 Props와 다르게, 컴포넌트 내에서 사용되는 상태 관리 변수이다. State를 사용하면 동작을 통해 컴포넌트를 재실행해 주며, 이를 통해 UI를 업데이트 할 수 있다.
사용법
우선, 수정 전 전체 코드를 보자.
그에 따른 뷰도 보자.
우리는 참으로 직관적인 UI의, '여기에글이떠야됨' 부분에 1, 2, 3번 a
태그를 누름에 따라 topics
라는 배열의 text
키의 값이 보이게 하고자 한다.
우선, State를 사용해야 하는지를 판단하자. App
에서 Nav
컴포넌트 내부의 a
를 클릭하면 App이 재생성되어야 하므로, State를 사용해야 한다.
그렇다면 State는 어떻게 사용할 수 있는가? State를 사용하기 위해서는, 먼저 문서 최상단에 React에서 제공하는 useState
를 사용한다는 import
문을 작성해야 한다.
이는 다음과 같이 작성한다.import { useState } from 'react';
2번 줄과 같이 useState를 불러오면, State 사용 준비를 마친 것이다. 이제 해야 할 것은, 새로운 State 변수(또는 상수)를 만드는 것이다.
State 변수(또는 상수)를 만들 때 사용하는 메소드는 useState
이다. 테스트와 시연을 위해, newState
라는 이름의 State를 한번 만들어 console.log
함수를 사용해 보자.
'아브라카다브라'라는 String 자료형의 값을 newState
라는 변수로 저장해 newState
를 확인해 봤더니, 배열로 확인된다.
이 배열의 0번째 값은 우리가 지정한 '아브라카다브라'라는 문자열이고, 1번재 값은 dispatchSetState()
라는 요상한 함수이다.
이렇게 나오는 이유는, 사실 useState
메소드가 배열을 반환하기 때문이다. 이 반환된 배열의 0번째 값은 State의 값, 1번째 값은 State의 값을 바꿀 때 사용하는 메소드이다.
따라서 주로 State를 선언할 때에는, 다음의 문법을 사용한다.
var [newState, setNewState] = useState(value)
이렇게 useState
를 사용하면, useState
의 0번째 값이 newState
에 저장되고, 1번째 값, 즉 setter가 setNewState
에 저장되어 두 가지의 변수(또는 상수)로 useState
를 구분하여 사용할 수 있게 된다.
이렇게 사용 문법을 알아보았으니, 다시 실습으로 돌아가 보자.
다음 활동들은 App
컴포넌트에서 거쳐야 할 과정이다.
- 방금 작성한 테스트 코드는 삭제하고,
a
태그의id
값을 담을 새로운 State를 제작한다. 기본값은 0번째a
인 '1번'을 지정하는, 0이다. - 만약
a
태그가 클릭되면 글을 바꾸도록,Nav
컴포넌트에Props
로 함수를 던져 준다. 이 함수는 클릭된a
태그의id
속성으로id
라는 State를 변경해 주므로, 파라미터는targetID
로 정한다. - '여기에글이떠야됨' 대신 동적으로 태그 내부 글을 변화시켜야 하므로, '여기에글이떠야됨'이라는 문자열을 중괄호 문법의
content
변수로 대체하여 작성한다. App
컴포넌트 실행 때마다 현재id
State를 체크하여content
의 값을 바꾸기 위해, forEach 문법을 이용해 현재id
State와topics[n].id
의 값을 비교한다.
이를 모두 작성한 코드는 다음과 같다.
25번 줄에서 id
State의 기본값을 0으로 설정했다. 26번 줄에서는 content의 기본값을 설정해 주었다.
33번 줄에서는 배열 topics
를 순회하며 배열 내 오브젝트 내의 id
가 id
State의 값과 같은지 확인했다.
39번 줄에서는 onChangeMode
를 통해 targetID
를 파라미터로 받아 id
State의 값을 targetID
의 값으로 바꾸는 함수를 props로 전달했다.
40번 줄에서는 article
태그 안의 내용을 중괄호 문법을 사용해 변수 content
로 변경했다.
이제 필요한 것은 Nav
컴포넌트에서 정수형의 id
를 targetID
파라미터로 넘겨주도록 설정하는 것이다.
9번 줄에서 페이지 새로고침을 막았고, 10번 줄에서 event.target.id
에 Number
메소드를 사용해 정수형의 targetID
를 넘겨주도록 하였다. (id
는 HTML 속성에서 String으로 저장되므로, Number
를 통해 바꿔 주어야 한다.)
이렇게 코드를 수정하고 나면, 위 사진과 같이 요구사항에 맞춰 잘 작동되는 것을 볼 수 있다.
이번 장에서 배운 State가 React 학습의 9부능선이란다. (egoing님의 말씀이다)
여기까지 잘 따라왔다면, 이 다음 과정은 잘 따라올 수 있을 것이다.
정리 3장은 여기에서 마무리하고, 4장에서는 CRUD 중 Create 기능을 React로 구현하는 것을 다뤄보겠다.
'프레임워크 · 라이브러리 > React' 카테고리의 다른 글
React 기초 정리 - 6장 (Delete 기능 구현, 마무리) (0) | 2024.04.12 |
---|---|
React 기초 정리 - 5장 (Update 기능 구현) (0) | 2024.04.12 |
React 기초 정리 - 4장 (CRUD, Create 기능 구현 + 객체 State의 변경) (0) | 2024.04.12 |
React 기초 정리 - 2장 (배포, 컴포넌트, Props + 중괄호 문법) (0) | 2024.04.12 |
React 기초 정리 - 1장 (React란, 개발 환경 설정, 폴더 구조) (0) | 2024.04.12 |