일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 알고리즘
- 부트캠프
- 부트캠프 #스파르타코딩클럽 #개발일지# #html
- querySelector
- 부트캠프 #스파르타코딩클럽 #개발일지# #TIL #Javascript #confirm #location.href
- Til
- 의사클래스
- 개발일지
- 부트캠프 #개발일지 #TIL #CSS속성 #float #clear
- appendChild
- useEffect
- 부트캠프 #CSS #개발일지 #TIL
- React
- 개발일지 #TIL #프론트엔드 #HTML
- CSS
- textContent
- JS예제
- 부트캠프 #개발일지 #TIL #그리드 #CSS
- 부트캠프 #개발일지 #TIL #FlexboxFroggy #displayflex #flexbox
- 특성선택자
- 깃허브오류
- 부트캠프 #CSS #개발일지 #TIL #박스모델
- 템플릿스트링
- ㅜㄹㄹ
- 결합선택자
- useState
- 리액트
- js
- 부트캠프 #개발일지 #TIL #Position #위치
- 부트캠프 #코딩 #개발일지 #프론트엔드 #CSS #TIL
- Today
- Total
나의 개발일지
[React] React Hooks - useState / useEffect / useRef 본문
useState
리액트 훅에는 여러가지 종류가 있는데
우선 공부할 것은 이젠 나름 익숙한 useState 이다!
useState의 기본 형태는
const [state, setState] = useState(initialState);
❗ ⭐ useState에서 짚고 넘어가야 할 포인트
1️⃣state는 변수, setState를 이용해 state의 값을 수정한다!
그리고 state가 만약 원시데이터가 아닌 객체 데이터 타입인 경우
그토록 강조하는 불변성을 유지해야 한다!
// 가장 기본적인 Hook
// 함수형 컴포넌트 내에서 가변적인 상태를 갖게 함
// 카운터 , TodoList
// const[state, setState] = useState(초기값);
// 함수형 업데이트란?
import "./App.css";
import { useState } from "react";
function App() {
const [number, setNumber] = useState(0);
return (
<div>
<div>Number State : {number}</div>
<button
onClick={() => {
// 기존 업데이트 방법
// --> 배치 업데이트
// setNumber(number + 1);
// setNumber(number + 1);
// setNumber(number + 1);
// 1씩 찍힘
// --> 렌더링이 잦다는 것은 성능에 이슈가 있는 것!
// 함수형 업데이트 방법
// --> 순차적으로 한 번씩 실행시킨다
// ()안에는 현재 상태의 스테이트 값을 불러온다
setNumber((currentNumber) => currentNumber + 1);
setNumber((currentNumber) => currentNumber + 1);
setNumber((currentNumber) => currentNumber + 1);
// 3씩 찍힘
}}
>
누르면 UP{" "}
</button>
</div>
);
}
export default App;
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
일반 사용법으로 사용하여 버튼을 눌러보면 1씩 증가한다
반면 함수형 업데이트 방식은 3씩 증가한다.
2️⃣ 두 개의 방식에 차이점은 무엇일까?
일반 업데이트 방식은 배치(batch)로 처리가 된다
버튼을 세 번 누르면 setNumber이 세 번 실행되어 3을 출력해야 하는데
리액트는 똑같은 명령을 최종적으로 모아 한 번만 실행시킨다.
아무리 많은 명령을 하더라도 단 한 번만 출력될 것이다
하지만 함수형 업데이트 방식은 3번을 동시에 명령을 내리면
그 명령을 모아서 순차적으로 각각 한 번씩 실행시킨다
웨이터가 손님에게 주문을 받을 때 메뉴 하나마다 주문을 받아 주방에 전달한다면
동선이 길어진다. 그래서 메뉴를 한 번에 주문을 받아 주방에 전달하는 방법이 가장 효율적인 것이다!!
useEffect
❗ ⭐ useEffect 가 언제 사용될까?
useEffect 는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이다
1. 어떤 컴포넌트가 화면에 보여졌을 때 무언갈 실행하고 싶다!
2. 어떤 컴포넌트가 화면에 사라졌을 때 무언갈 실행하고 싶다! (return, clean up)
useEffect 는 화면에 렌더링 될 때 useEffect 안에 있는 console.log가 실행된다
--> 핵심 기능!!
// src/App.js
import React, { useEffect } from "react";
const App = () => {
useEffect(() => {
// 이 부분이 실행된다.
console.log("hello useEffect");
});
return <div>Home</div>;
}
export default App;
그런데, useEffect의 핵심기능인 렌더링 될 때마다 실행되는 것은
비효율적인 성격을 갖는다
<예시를 통해 살펴보기>
function App() {
const [value, setValue] = useState("");
useEffect(() => {
console.log(`Hello : ${value}`);
}, [value]);
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
></input>
</div>
);
}
export default App;
input 창을 만들고 값을 입력하여 콘솔에 '반가워요'를 입력해 봤더니
입력할 때마다 찍히는 걸 볼 수 있다
state 값이 바뀌고 렌더링 되면서 바뀔 때마다 useEffect가 실행된 것이다
그래서 콘솔이 브라우저에 한 번만 찍히게 하려면
의존성 배열을 이용하여 제어할 수 있다
의존성 배열(dependency array)란 무엇일까?
--> 배열에 값을 넣으면 그 값이 바뀔 때만 useEffect를 실행하는 것!
(1) 의존성 배열에 값이 없는 경우
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [value, setValue] = useState("");
useEffect(() => {
console.log("Hello");
}, []); //의존성 배열이기 때문에 배열의 형태로 나타낸다
// input 창에 값을 입력해도 변하지 않고 처음 렌더링 한 상태로 유지된다
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
></input>
</div>
);
}
export default App;
아까 코드에서 useEffect( ),[ ] 만 추가되었다!
결과는 값을 아무리 입력해도 "Hello"만 뜨는 걸 볼 수 있다
다른 값은 전혀 실행되지 않고 있다
--> 정리하자면 useEffect( ),[ ] 여기서 두 번째 인자에서 배열이 들어가는데
어떤 함수를 컴포넌트가 렌더링 될 때 단 한 번만 실행하고 싶으면 [ ] 빈 배열을 쓰면 된다!
(2) 의존성 배열에 값이 있는 경우
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [value, setValue] = useState("");
useEffect(() => {
console.log(`Hello : ${value}`);
// return 안에 로직은 화면에서 사라졌을 때(컴포넌트가 죽을때) 실행되는 것이다
return () => {
console.log("사라집니다");
};
}, [value]);
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
></input>
</div>
);
}
export default App;
useEffect( ),[value] 이번엔 두 번째 인자에 [value] 값을 넣었다
value는 state 이고, state 값이 변경되면 input을 입력할 때마다 그 값이 변할테니
useEffect가 실행이 될 것이다!
useRef ( 1 )
useRef는 DOM 요소에 접근할 수 있도록 하는 React Hook이다
import React, { useRef, useState } from "react";
const style = {
border: "1px solid black",
margin: "10px",
padding: "10px",
};
function App() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
const stateCountButtonHandler = () => {
setCount(count + 1);
};
const refCountButtonHandler = () => {
countRef.current++;
console.log(countRef.current);
};
return (
<>
<div style={style}>
state 영역 {count}
<br />
<button onClick={stateCountButtonHandler}>state 증가</button>
</div>
<div style={style}>
ref 영역 {countRef.current}
<br />
<button onClick={refCountButtonHandler}>state 증가</button>
</div>
</>
);
}
export default App;
state는 state 값이 변경됨에 따라 계속해서 렌더링이 된다
(화면이 카운트된 숫자가 나타날 때마다 렌더링이 되는 것임)
반면 useRef는 값이 증가해도 렌더링이 되지 않는다
둘 다 상태관리를 하지만 렌더링의 차이가 있다
useRef ( 2 )
렌더링 됐을 때 자동으로 아이디에 포커싱이 되도록 만들기
import React, { useEffect, useRef, useState } from "react";
function App() {
const idRef = useRef("");
const pwRef = useRef("");
const [id, setId] = useState("");
// id 포커스
useEffect(() => {
idRef.current.focus();
}, []);
// pw 포커스
// useEffect(() => {
// pwRef.current.focus();
// }, []);
useEffect(() => {
if (id.length >= 10) {
pwRef.current.focus();
}
}, [id]);
return (
<>
<div>
{/* <input>에 ref라는 속성이 있다.(DOM에 접근가능) 위에 useRef랑 연결가능 */}
아이디 :{" "}
<input
value={id}
onChange={(e) => {
setId(e.target.value);
}}
type="text"
ref={idRef}
/>
</div>
<div>
비밀번호 : <input type="password" ref={pwRef} />
</div>
</>
);
}
export default App;
10자리를 입력하면 바로 비밀번호로 포커싱이 된다
useRef로 포커싱이 되게 하는 방법 말고
onChange에서 바로 하는 방법도 있다
<input
value={id}
onChange={(e) => {
setId(e.target.value);
if (id.length >= 10) { // state 가 업데이트 되기 직전!
pwRef.current.focus();
}
}}
type="text"
ref={idRef}
/>
하지만 문제점이 있다
11자리를 입력해야 비밀번호로 포커싱이 이동한다
그 이유는 리액트의 배치업데이트 때문이다.
'React' 카테고리의 다른 글
[React] 에러 발생 및 해결 Cannot read properties of undefined (1) | 2023.11.23 |
---|---|
[React] JSON과 비동기통신 실습 (2) | 2023.11.14 |
[React] Styled Components - GlobalStyles (전역스타일링) / CSS RESET (0) | 2023.11.08 |
[React] styled Components 사용하기 (0) | 2023.11.07 |
[React] 리액트에서 UUID 사용하기 (0) | 2023.11.05 |