TIL_56_Hook

poohv7·2021년 3월 31일
0
post-thumbnail

함수형 컴퍼넌트

Hook은 클래스 안에서는 동작하지 않는다.

왜 사용?

컴퍼넌트 사이에서 상태와 관련된 로직을 재사용하기가 어렵다. (HOC, render props)
개발을 하다보면 가끔 상태 관련 로직을 컴퍼넌트 간에 재사용하고 싶은 경우가 생긴다.
HOC (higher-order-components 와 render porps가 전통적인 방법) 이 둘과는 달리 컴퍼넌트 트리에 새 컴퍼넌트를 추가하지 않고도 가능하게 해준다.

각 컴퍼넌트의 state는 완적히 독립적.
Hook은 state 그 자체가 아니라 상태관련 로직을 재사용하는 방법
각각의 Hook 호출은 완전히 독립된 state를 가짐.
심지어 한 컴퍼넌트 안에서 같은 custom Hook을 두 번 쓸수도 있음.

class는 사람과 기계를 혼동시킨다.
this 는 항상 최신값을 가져온다.
그래서 this 는 바뀌기가 쉬운 성질
그래서 오류를 발생시킨다.

그럼 왜 우린 클래스형 컴퍼넌트를 쓴거야?

state 와 라이프 사이클 때문.
마치 생명체처럼 클래스로부터 한번 인스턴스가 생성이 되고 나면 독립적으로 움직일 수 있어서
반면 함수는 한번 호출되고 메모리 상에서 사라짐
-> 즉, state와 라이프 사이클 불가능.

그러나 클래스를 사용해보니 해결하기 힘든 여러 문제가 계속 존재하게 됨

**그래서. 2018년에 Hooks 공개!
**

그럼 어떻게 state, 라이프 사이클을 구현하지?
-> 바로 클로저 (함수 안의 함수)

훅 규칙

  1. 최상위에서만 Hook을 호출해야 한다
  • 반복문, 조건문 혹은 중첩된 함수 내에서 Hook을 호출하면 안된다.
    이 규칙을 따르면 컴퍼넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장된다. React가 useState 와 useEffect 가 여러 번 호출되는 중에도 Hook의 상태를 올바르게 유지할 수 있도록 해준다.
  1. React 함수 컴퍼넌트 내에서만 Hook을 호출해야 한다.

Hooks는 React를 대체하지 않는다.

우리가 배울 훅 두 개

useState?

const [state, setState ] = useState(initialState);
//구조분해 할당

상태 유지 값과 그 값을 갱신하는 함수를 반환하는 것.
최초로 랜더링을 하는 동안,
반환된 state는 첫 번째 전달된 인자 (initialState)의 값과 같다.
setState 함수는 state를 갱신할 때 사용.

예시)

constructor() {
  super();
    this.state = {
     id: 0,
     name: "",
     place: {},
 }
}

위에서는 this.setState({id : 1})
이렇게 접근했지만

const [id, setId] = useState(0);
const [name, setName]= useState(""),
const [place, setPlace] = useState({});

여기에서는 setId(1) 이렇게 접근하면 됨.

함수는 뭐다? 더 이상 참조하는 곳이 없으면 메모리 상에서 사라진다!

클로저? 자신이 생성될 시점의 환경을 기억하는 함수.

useState 함수는 인자로 어떤 값을 받아온다 -> 그 값이 초기값.

const useState = (init = undefined) => {
let value = init
const getter = () => value //클로저
const setter = next => (value = next) //클로저

return [getter, setter]
}

위의 코드를 보면
인자로 들어온 값이 value 라는 변수에 담김.
getter라는 함수가 value를 반환하고 있음.
setter라는 함수는 next 라는 인자를 가지고 있고 next 라는 인자를 활용해서 value를 반환하고 있음
value를 next로 업데이트 해주고 있음
함수를 리턴 해주고 있음.

const [state, setState] = useState('클로저')

위의 애들을 구조분해 할당 해준 것.

state()
//클로저 라는 값이 나옴. -> 초기값.
setState("어려워!") 
//어려워! 라는 값이 나옴 
//-> next가 value를 바꿔주고 있기 때문.
state() 
//어려워! 가 뜸. setState해주었기 때문.

useState 내에서 첫번째는 state고, 두 번째는 setState다.

useEffect?

컴퍼넌트 디드 마운트, 컴퍼넌트 디드 업데이트, 컴퍼넌트 윌 언마운트와 같은 목적으로 제공되지만 하나의 API로 통합된 것.

useEffect(function);
useEffect(() => {}, [count])
//의존성 배열(배열 안에 담긴 값들을 추적, 그 때마다 업데이트)

함수처럼 생겼다. 콜백.
함수형태의 인자가 들어가있음.

useEffect(() => {
console.log("componentDidupdate")
})
//의존배열 자체가 없음
useEffect(() => {
console.log("componentDidmount")
return () => console.log("componentWillUnmount")
}, [])
//리턴 사용, 빈 의존배열
useEffect(() => {
console.log("componentDidMount")
console.log("componentDidUpdate")
return () => console.log("???")
}, [state])
//상태값을 비교해준 것.
//무한루프에 빠지지 않게 해주기 위해서.
//의존배열안에 상태값을 넣어주는 것.
//상태값이 변경될 때마다 유즈이팩트가 시작됨.
//리턴은 윌언마운트 역할을 함.
const [color, setColor] = useState("blue")

const handleBtnColor = () => {
setColor("red")
}
useEffect(() => {
console.log(color)
}, [color])
//처음엔 blue 값이 찍히고,
//컬러가 바뀔 때마다 useEffect가 실행되기 때문에 red 로 바뀜.

0개의 댓글