1차 프로젝트를 정신없이 후다닥 끝내고 정신이 들려는 순간 바로 시작된 2차 프로젝트!!!
1차와 똑같다면 위코드 부트캠픅라 아니지... 이번 프로젝트는 1차 프로젝트에는 상상도 못한 정체가 기다리고 있었는데
그것은 바로 함수형 컴포넌트 React Hooks 와 Styled Components
당황하지 않고
오늘은 함수형 컴포넌트 React Hooks에 대해 알아보자
리액트 컴포넌트는 클래스형 컴포넌트 (Class Component)와 함수형 컴포넌트(Functional Componen)
로 나뉜다. 기존의 개발방식은 일반적으로 함수형 컴포넌트를 사용하되 state이나 Life Cycle Method를 사용할 때만 클래스형 컴포넌트를 사용하는 방식이었다.
그 이유는 클래스형 컴포넌트가 함수형 컴포넌트에 비해 가지는 단점 때문이다!
1.코드가 길고 복잡하다
2.컴포넌트 사이에서 상태와 관련된 Logic을 재사용하기 어렵다
이에 반해 hooks를 활용한 함수형 컴포넌트에서는 원하는 기능을 함수로 만든 후(hook) 필요한 곳에 훅 집어 넣어주기만 하면 되기 때문에 로직의 재사용이 가능해진다.
3. 함수형 컴포넌트의 성능
함수형 컴포넌트의 성능에 관한 글
함수형컴포넌트에 비해 가지는 이런 단점에도 불구하고 그동안 클래스형 컴포넌트를 사용했던 이유는 state 관리
와 Life Cycle method
의 사용때문이었다. 복잡하고 뚱뚱하지만 클래스의 힘을 빌려야만 React가 원활하게 작동하기 때문이다.
하지만 Hooks의 등장으로 함수형 컴포넌트에서도 이러한 클래스형 컴포넌트의 작업을 할 수 있게 되었다
기존의 클래스형 컴포넌트가 가지고 있던 복잡성, 재사용성의 단점들까지 해결하면서 말이다
React에는 4가지의 Built-in Hooks(useState, useEffect, useRef, useReducer) 등이 있고 이외에도 다양한 커스텀 훅이 존재하지만 일단 가장 기본적이고도 핵심적인 역할을 하고 있는
useState
와useEffect
두 가지 Hook을 학습해보자~!~! ~👌
const [state, setState] = useState(initialState);
상태 유지 값과 그 값을 갱신하는 함수를 반환한다. 최초로 렌더링을 하는 동안, 반환된 state(state
)는 첫 번째 전달된 인자(initialState
)의 값과 같다.
setState
함수는 state를 갱신할 때 사용한다. 새 state 값을 받아 컴포넌트 리렌더링을 큐에 등록한다.
setState(newState); // setState와 동일하게 비동기 업데이트
다음 리렌더링 시에 useState
를 통해 반환받은 첫 번째 값은 항상 갱신된 최신 state가 된다.
// 클래스형 컴포넌트
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
함수형 컴포넌트
import React, { useState } from 'react';
// 함수 컴포넌트
function Example() {
// 새로운 state 변수를 선언하고, count라 부르겠습니다.
const [count, setCount] = useState(0);
const [isModalActive, setIsModalActive] = useState(false);
// 안 좋은 예시
const [state, setState] = useState({
color: "red",
isActive: true
})
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
<button onClick={() => setIsModalActive(!isModalActive)}>modal btn</button>
</div>
);
}
Q) useState()
하나에서 모든 상태 값을 관리하면 안될까요?
function Box() {
const [state, setState] = useState({ left: 0, top: 0, width: 100, height: 100 });
// ...
}
A) However, we recommend to split state into multiple state variables based on which values tend to change together.
function Box() {
const [position, setPosition] = useState({ left: 0, top: 0 });
const [size, setSize] = useState({ width: 100, height: 100 });
useEffect(() => {
function handleWindowMouseMove(e) {
setPosition({ left: e.pageX, top: e.pageY });
}
// ...
useState
하나에 여러 상태를 관리하는 방법은?회원가입 사이트 같이 인풋창이 많은 경우 모든 상태값을 State으로 관리하는 건 비효율적이다.
const [userInfo, setUserInfo] = useState({
firstName: "",
lastName: "",
email: "",
userName: "",
password: "",
});
const handleInput = (name, e) => {
setUserInfo({ ...userInfo, [name]: e.target.value });
};
이렇게
useState
의 파라미터로 객체를 전달한다
useEffect 는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있는 기능이다.
쉽게 말하면, 클래스형 컴포넌트의 componentDidMount + componentDidUpdate 를 합친 형태라고 이해하면 된다!