React/To-do 앱

React_to-do_3

oyatplum 2023. 1. 28. 21:21

3. To-do_1

: react-hooks란 무엇인고

 

 

 

React Hooks

지금까지 사용한 class 없이 state를 사용할 수 있는 새로운 기능이다.

 

 

 

리액트에는 클래스 컴포넌트와 함수형 컴포넌트가 있었지!!

여기서 리액트는 주로 클래스 컴포넌트를 사용하고 리액트 훅스는 주로 함수형 컴포넌트를 사용한다...

 

 

 

클래스 컴포넌트와 함수형 컴포넌트를 비교해볼까

 

클래스 컴포넌트 : 더 많은 기능 제공, 더 긴 코드의 양, 더 복잡한 코드, 더딘 성능

함수형 컴포넌트 : 더 적은 기능 제공,  짧은 코드의 양, 더 심플한 코드, 빠른 성능

 

 


 

 

그렇다면 함수형 컴포넌트가 클래스 컴포넌트에 비해 적은 기능을 제공한다면.... 어떤 기능을 제공하지 못 하는걸까??

 

리액트에는 생명 주기가 있다.

이는 Mounting > Updating > Unmounting 단계로 이루어져 있는데 각각 컴포넌트가 시작될 때, 업데이트 될 때, 사용되지 않을 때로 나뉜다.

이러한 생명 주기가 원래 리액트 훅스에는 없었다!!

 

 

 

그런데 React 16.8 Hooks 업데이트로 리액트 훅스에서도 생명 주기를 사용할 수 있게 되었다고 한다....호호

그리고 클래스 컴포넌트보다 코드를 훨씬 간결하게 쓸 수 있다..

 

 


 

 

또 하나 장점으로 Hooks는 HOC 컴포넌트Custom React Hooks로 대체해서 Wrapper 컴포넌트를 줄이게 된다.

 

우선 HOC 컴포넌트가 무엇인지 살펴보자.

 

 

 

HOC 컴포넌트

Higher Order Component로 화면에서 재사용 가능한 로직을 분리해 컴포넌트로 만들고 재사용이 불가능한 UI 같은 부분은 파라미터로 받아 처리하는 방법이다.

 

즉, 예를 들어 A페이지와 B페이지에서 유저 리스트를 가져오는 코드를 동일하게 사용한다고 하면.. 아무래도 코드가 중복되니까 성능이 안 좋지!!

그래서 중복되는 소스 코드를 HOC 컴포넌트로 만들어 주는 것이다. 우선 지금은 이 정도로만 이해하자..!

 

Hooks가 나오기 전에는 이 방법이 추천되었지만 여기서도 문제가 생긴다. 그게 Wrapper라는 것!!

 

 

Wrapper 컴포넌트

위의 예시에서 A페이지가 유저를 위한 HOC, 테마를 위한 HOC, 언어를 위한 HOC 등을 계속 반복적으로 중첩하여 사용한다면... 즉, Wrapper가 너무 많아지면 너무 복잡해서 데이터의 흐름을 파악하기 어렵다.

 

 

따라서 이러한 문제점을 해결한 것이 Custom React Hooks이다.

 

 

Custom React Hooks

위의 예시에서 HOC 컴포넌트를 계속 감싸주면서 중첩시켰다면...  HOC를 훅스로 만들고 그냥 A페이지가 그 훅스를 사용하도록.. 감싸는 것이 아니라 사용하도록..! 해서 더 간결하게 사용하는 것이라고 한다.... 따흑 어렵구만...

 

 

 

 

뭐.. 그롷다... 아직 이 개념들이 확 와닿지 않지만 언젠가 유용하게 쓰일 것이니....... 따흑따흑....

 

 


 

 

3. To-do_2

: todo 앱을 클래스 컴포넌트에서 함수형 컴포넌트로 바꾸기

 

 

 

위의 리액트 훅스를 이용해서 기존의 클래스 컴포넌트를 함수형 컴포넌트로 바꿔보자!!

 

 

 

우선 컴포넌트 자체를 바꿀 것이다.

이렇게 클래스 형태에서 함수 형태로!!


 

 

클래스 컴포넌트에서는 render 함수 내에서 return을 해줬다면 함수형 컴포넌트에서는 render 없이 바로 return 할 수 있다.

 

이렇게 return 위에 render함수를 없애주기만 하면 된다.

 


그리고 클래스 컴포넌트에서 extends 했던 component도 function으로 바뀌었으니까 import에서 component도 삭제!!

이제 본격적으로 state 부분을 useState Hook을 사용해서 표현할 것이기 때문에 component 부분에 useState를 써준다.

 

 


 

 

이제부터 쬐깐 복잡한디...

 

 

주석처리 해준 state 부분은 아래처럼 바뀐다.

 

const [getter, setter]로 생각하고 첫 번째 원소는 상태를 저장할 변수, 두 번째 원소는 상태를 갱신할 함수이다.

클래스 컴포넌트에서 this.state를 갱신할 때 this.setState를 사용한 것과 비슷하다고 보면 쉽다!!!

 

 

그리고 todoData는 원래 빈 배열이니까 useState 내부에 빈 배열을, value는 원래 빈 문자열이니까 useState 내부에 빈 문자열을 넣어준 것이다.

 

 

 

따라서 this.state.todoData 는 그냥 todoData로 바뀌고 this.state.value는 그냥 value로 싹 다 바꿔주자!!

 

그리고 state를 새로운 값으로 업데이트 할 때 this.setState({value: ""})는 그냥 setValue("")로 처리한다. setValue가 setter에서 함수니까ㅎㅎ

 

 

즉,

 

이렇게 주석 처리한 부분을 아래의 코드와 같이 바꾸는 것이다.

(간단하군!!!!)

 


 

 

그리고 여기가 좀 생각을 해야 하는데

 

 

흠냐.... 기존 클래스 컴포넌트 코드에서는 기존 todoData 배열을 newTodo 배열로 업데이트 할 때, ...todoData로 기존 배열을 가져오고 newTodo 배열을 합췌!!! 하는 방식이었다면...

 

지금 setter에서 이전 state를 가지고 오기 위해서는 인수에 함수를 이용할 수 있다.

즉, 위의 코드처럼 이전 state인 todoData를 가져오기 위해 인수에 prev를 이용하는 함수를 작성한 것이다.

prev가 '이전'이라는 의미니까..! 어렵게 생각하지 않아도 된다!!

 

그리고 입력 창에 적힌 글을 삭제하기 위해 value를 초기화 한 것은 역시나 setValue를 사용하면 된다.

 

 

 


 

이번엔 함수 및 변수를 정의하는 방법도 바꿔줘야 한다.

 

우선 간단하게 함수에는 함수명 앞에 const나 let을 붙여주면 된다.

그래서 모든 함수 앞에 const을 냅다 붙여뻐려~~~~

 

 

이제 함수나 메소드를 사용하는 방법도 바꿔주는데

this.함수명 을 사용했던 것에서 this.을 없애면 끝ㅋㅋ

 

 

 


 

 

3. To-do_3

: state와 props

 

 

우선 state는 지금까지 사용했던 것처럼

1. 부모 컴포넌트에서 자식 컴포넌트로 데이터를 보내는 것이 아니라 해당 컴포넌트 내부에서 데이터를 전달한다.

2. state는 변경 가능하다.(mutable) (클래스 컴포넌트에서는 setState를, 함수형 컴포넌트에서는 setter를 사용한 것처럼)

3. state가 변하면 리렌더링 된다.

 

반면 props

1. properties의 줄임말이다.

2. 부모 컴포넌트로부터 자식 컴포넌트에게 데이터를 전달하는 방법이다.

3. 읽기 전용(immutable)으로 자녀 컴포넌트에서는 변경 불가하고 부모 컴포넌트에서 state를 변경시켜야 한다.

 

 


 

3. To-do_4

: 할 일 목록 부분을 위한 컴포넌트 생성하기(컴포넌트 분리하기)

 

 

 

지금까지 작성한 코드는 모두 App.js에 들어가 있어서 관리의 어려움이 있다.

 

따라서 제목 부분은 App 컴포넌트에, 할 일 목록들은 리스트 컴포넌트에, 입력 창 부분은 Form 컴포넌트에..

이런 식으로 분리를 해주면 재사용성이 증가하고 구분하기에도 유용하다.

 

 


 

그래서 먼저 리스트 컴포넌트를 만들어보자!!

 

아렇게 src 폴더에 components 폴더를 새로 만들고 List.js 파일도 새롭게 작성했다.

 

 

그리고 함수형 컴포넌트로 작성을 해줄건데

여기서 !!!!

 

 

이렇게 es7+(extension)을 설치해주면

 

 

함수형 컴포넌트는 rfc를, 클래스 컴포넌트는 rce를 작성해주면

 

 

이렇게 바로 함수형 컴포넌트가 자동으로 만들어진다!!! useState도 작성하면 자동으로 state 형태가 나온다!!

 

편리하군.....헤헤

 


 

 

아무튼 리스트 컴포넌트에 리스트와 관련된 부분만 가져와야 한다.

 

그래서 우선

 

 

리스트와 관련된 UI를 가져왔다.

 

 

 

 

이제 state를 가지고 올 것인데 현재 필요한 todoData state를 그대로 가져와서 써도 되지만... todoData state는 다른 컴포넌트에서도 사용하기 때문에 props를 이용할 것이다!!

 

 

이렇게 App.js에서 List를 import 하고

List를 작성한 부분에 todoData를 내려준다.

 

이렇게 말이지!!!!

 

 

이제 다시 List 파일로 돌아와서 이렇게 부모 컴포넌트에서 전달해준 것을 받아와 써야 하기 때문에

 

이렇게 인자로 props를 써줘도 되지만 그러면 props.todoData 이런 식으로 사용해야 하기 때문에

 

 

 

아예 중괄호를 사용하여

이렇게 todoData를 받아오면 바로 todoData를 사용할 수 있다. 헤헤 신기해

 

 

 

이제 함수도 가져오자

이렇게!! 그럼 setTodoData에도 에러가 뜨는 것을 확인할 수 있다.

 

setTodoData는 todoData를 업데이트 해주는 setter이기 때문에 이것도 App.js 컴포넌트로부터 내려 받아야 한다.

 

 

 

그래서

이렇게 setTodoData도 써주고

 

인자로 setTodoData도 함께 받아오면 된다!!

 

 

 

우선 여기까쥐~!

'React > To-do 앱' 카테고리의 다른 글

React_to-do_6  (0) 2023.01.31
React_to-do_5  (0) 2023.01.30
React_to-do_4  (1) 2023.01.29
React_to-do_2  (0) 2023.01.27
React_to-do_1  (1) 2023.01.27