컨텐츠 내 위젯


React Hook Angular / React

이전에는 주로 class형 개발을 해왔기 때문에 hook을 거의 쓸 필요가 없었다. 그러나 이젠 클래스형이 아닌 함수형 컴포넌트가 주를 차지하게 되고 그 기능을 hook을 통해 호출할 수 있다. ( useState, useRef 등의 바로 이해가 안되는 예제가 있긴 하지만.. )

그래서 v16 이전의 React 책들을 보면 hook에 대한 설명은 거의 없다시피 하다... ^^;; 기존에 쓰이던 방식과 비교해서 볼 수 있도록 적어두도록 했다.


1. useState(현재) 
기존에 있던것과 역할은 똑같다. 그러나 사용 방법이 조금 다른데 "구조분해"를 통해 좀 더 편리하게 이용할수 있다는걸 차이점으로 볼 수 있다. 그리고 state를 변환할 setter를 지정할 수 있다.

1
2
3
4
5
6
function exampleAge() {
const [age, setAge] = useState(30);

// 초기값 this.state.age = 30;
// 바꾸고 싶프면 this.setAge(31);
}


2. useEffect(현재)
컴포넌트가 렌더링 될 때마다 원하는 작업이 실행되도록 설정 할 수 있는 기능


 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React, { useState, useEffect } from 'react';

function Example() {
const [count, setCount] = useState(0); // ①
useEffect(() => { // ②
// 문서의 타이틀을 업데이트합니다
document.title = `You clicked ${count} times`;
});

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}



3. useContext
기존의 Context - Provider - Consumer API를 사용하기 쉽게함... 기존에 Provider 이랑 Consumer를 써서 내려야 하는걸 없앰..

1
2
3
4
5
function Example() {
const locale = useContext(LocaleContext);
const theme = useContext(ThemeContext);
// ...
}



4. useReducer
리덕스를 편히 옮겼다고 생각하면 된다, 즉 얘가 redux의 connect 역할을 해준다고 보면 된다. 첫번째 매개변수로는 리듀서를 넣어주면 되고, 두번째는 초기값이다. 

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
onst initialState = {count: 0};

function reducer(state, action) {
switch (action.type) { // 여기가 액션 생성자들 넣어주는데
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}

function Counter() {
const [state, dispatch] = useReducer(reducer, initialState); // connect 역할 해줌
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}


하도 여러군데에서 응용하기도 하고 헷갈리니 전체적인 리덕스 흐름도 적어보자.

1) 스토어에  쓸 state를 만든다. 
2) 특정 액션 타입에 어떤 행위를 할건지 매개변수로 받을 리듀서를 생성해 놓는다. (여기서 쓰이는 매개변수들은 나중에 dispatch에서 받을 것이다)
3) 스토어가 createStore를 통해 자신이 부가적으로 쓸  state와 리듀서 등을 등록한다.
4) 원하는 컴포넌트가 reducer를 참조할 수 있도록 connect 해준다.
5) connnect 하면 commit, dispatch 를 통해 리듀서에 접근할 수 있도록 해주니 이를 통해 store에 원하는 변경사항만 쏙 바뀌게끔 해준다. (원하는 변경사항만 바뀌기 때문에 side effect를 제어 해 주어야 하고 이 때문에 reducer는 순수함수로만 구성되어 있어야 한다.)

5. useMemo 
기존에 연산했던 값을 기억하고 있다가 재사용한다. (메모리 및 성능향상)

1
2
3
4
5
6
7
8
9
function reducer(state, action) {
const [age, setAge] = useState(10);
useMemo(()=> cosole.log('나이를 먹었어요'),[this.state.age]);

this.updateAge = () => this.setAge(11);
}

reducer().updateAge();
// 나이를 먹었어요.


6. useCallback 
기존에 사용했던 함수를 기억하고 있다가 재사용한다. (메모리 및 성능향상)


7. useRef
예전에 보면 ref 속성에 주로 쓰던 패턴이 있는데 그걸 깔끔하게 바꾼 것이다. 장점은 캐싱되기 때문에 렌더 호출할때마다 굳이 저걸 또 안탄다고는 하는데 실제 돌려서 확인해 보아야 한다.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function TextInputWithFocusButton() {
const inputEl = useRef(null);
// 예전방식이랑 이렇게 매칭된다.
const oldEl = (e: null | HtmlInputElement) => e;
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<input ref={oldEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}



덧글

  • 링고파이 2021/04/29 23:27 # 답글

    그동안 인터넷에 있는 글들만 보고 정리했는데 다시 책을 보고 이전에 내가 작성했던 내용을 보니 부끄럽습니다....
댓글 입력 영역