[React] React hook #1

초이·2024년 5월 20일

🌐 React

목록 보기
1/4
post-thumbnail

🌐 React Hook


✅ useState


💡 값이 3씩 더해지는 코드를 작성해보자

숫자를 세는 count를 useState로 작성하면 아래와 같다.

const [count, setCount] = useState(0);

버튼을 누를 때 숫자가 3씩 증가되는 onClick 함수를 작성할 때 함수 안에

setCount(count + 1);
setCount(count + 1);
setCount(count + 1);

이런 방식을 이용하려고 한다면, 리렌더링 될 때마다 count가 3씩 더해질까?


❗ 답은 "안된다" 이다.


react에서는 값을 효율적으로 업데이트 하기 위해서 업데이트 하려는 것을 한번에 모아서 처리하려고 한다.

따라서, setCount(count + 1)이 3번 실행되는게 아니라 한번에 모아서 한번만 실행되기 때문에 1만 증가하는 것이다.

반면에

 setCount((prev) => prev + 1);
 setCount((prev) => prev + 1);
 setCount((prev) => prev + 1);

이렇게 작성하게 된다면

prev 값에 1이 더해진 값이 다시 prev로 들어가게 되면서 증가된 값이 다음 setCount로 return되기 때문에 원하는대로 3이 증가가 된다.
따라서 반복적으로 set을 써야할 때 return한 값을 넘겨주는 식으로 써야 원하는대로 코드가 작성된다.

배치 업데이트

react가 더 나은 성능 개선을 위해, 여러개의 state 업데이트를 한번의 리렌더링으로 묶어서 진행하는 것을 말한다.



✅ useEffect


input value를 얻기 위해 onChange에서 setValue를 쓴다면, 값이 입력될 때마다 리렌더링이 되기 때문에 onChange에서 setValue를 하는 것은 리소스 낭비가 크다고 할 수 있다.

의존성 배열 : 배열 안의 값이 바뀔 때만 useEffect를 실행

//모든 state 값이 변경 될 때 마다 실행
useEffect(()=>{
	console.log('hi');
})

//최초 한 번만 실행
useEffect(()=>{
	console.log('hi');
},[])

//count값이 바뀔 때만 실행
useEffect(()=>{
	console.log('hi');
},[count])

useEffect의 생애주기

useEffect(() => {
    console.log("mount");
    return () => {
      console.log("unmount");
    };
  }, []);


✅ useRef


const ref = useRef("초기값");
console.log(ref); // 초기값

ref.current = "바꾼 값";
console.log(ref); //바꾼 값

useRef는 useState와 마찬가지로 값을 저장하는 것이지만, useRef의 값이 바뀐다고 렌더링이 일어나지 않는다는 게 가장 큰 차이점이다.



✅ useContext


redux를 배울 때 중요한 개념이다.

react context

react의 데이터 흐름은 일반적으로 부모 컨포넌트 → 자식 컴포넌트이다.

하지만 컴포넌트가 늘어나면 계속해서 props를 넘겨줘야하는 “props drilling 현상이 일어나게 된다.

prop drilling?

  1. props의 값이 너무 깊어지면 어떤 컴포넌트에서 왔는지 파악하기 어려워짐(가독성 떨어짐)
  2. 오류 추적이 힘드니 유지보수가 힘듦

context API!

특정 영역 안에서 state를 공유하는 개념이다.

useContext를 이용해서 전체 데이터 관리를 하게 한다.

전역 데이터의 개념.

  • createContext : context를 생성
  • useContext: context를 구독하고 해당 context의 현재 값을 읽음
  • Provider: context를 하위 컴포넌트에게 전달

Context API 사용하는 방법

  • 컴포넌트
    조부모님 > 부모님 > 본인
  • context 파일
    FamilyContext.js 안에 context를 생성
  • FamilyContext.js
import { createContext } from 'react';

//context를 생성
export const FamilyContext = createContext(null);
  • GrandParents 컴포넌트
const GrandParents = () => {
	const houseName = "스파르타";
	const pocketMoney = 10000;
	
	return (
		<FamilyContext.Provider //provider로 하위 컴포넌트에 전달
			value={{
			houseName,
			pocketMoney,
			}}
		>
			<Parents />
		</FamilyContext.Provider>
	)
}
  • Child 컴포넌트
const Child = () => {
	//useContext를 이용해 FamilyContext의 값을 구조분해 할당해서 받음
	const {houseName, pocketMoney} = useContext(FamilyContext);
	
	return (
		<div>
			우리 집 이름은 {houseName} 이고
			용돈을 {pocketMoney} 만큼 받았어요
		</div>
	)
}

이렇게 전역으로 데이터를 관리하면, parents 컴포넌트를 거치지 않고 child 컴포넌트로 값을 전달할 수 있다.

문제점?

하지만 이렇게 전역으로 관리하게 되면 생기는 문제점이 있는데, Provider로 관리한 데이터 값이 바뀌게 된다면 useContext를 사용하고 있는 모든 컴포넌트가 리렌더링 되는게 문제가 된다.

profile
개발 일기장

0개의 댓글