Props
는 컴포넌트에 값을 전달해줄 때 사용한다. 넘겨줄 수 있는 값은 변수, 배열, 객체, 함수 등 자바스크립트 요소 모두 가능하다.
단, props는 읽기전용
으로 값이 변경되어서는 안 된다. props의 값을 변경하고 싶다면, props를 직접적으로 변경하는 것이 아닌 새로운 변수를 선언하여 사용한다. 또한, 데이터는 부모요소에서 자식요소로만 전달이 가능하다.
props는 HTML 속성을 통해 컴포넌트로 전달된다. <컴포넌트명 속성="값" />
사용할 때는 {중괄호}를 사용하며 함수형 컴포넌트에선{props.속성}
으로, 클래스형 컴포넌트에선 {this.props.속성}
으로 호출된다.
// props 사용법1 - props.속성로 받아오기
function Hi(props) => {
return <h1>Hello, {props.name}</h1>;
}
// props 사용법2 - {속성}로 받아오기
function Hi({name}) => {
return <h1>Hello, {name}</h1>;
}
<Hi name="홍길동" /> // name(속성)으로 홍길동이란 값을 전달
⭐ Props는 함수의 매개변수라고 생각하면 좋다.
data-
또는 aria-
로 시작하는 속성은 예외)className
, for는 htmlFor
로 기존 HTMl과 달리 작성하는 속성도 있다.checked
와 value
는 초기값을 의미하는 것과 달리, 리액트에서는 현재 값을 의미한다. 따라서 초기값을 설정하려면 defaultChecked
, defaultValue
로 설정해줘야 한다는 점을 유의해야 한다.key
: 리액트가 항목을 안전하게 식별할 수 있도록 배열에 고유성을 부여하기 위함.dangerouslySetInnerHTML
-> 사용 권장 안 함State
는 컴포넌트의 현재 저장된 값이며, 변할 수 있는 값이다. 리액트는 값이 변경된 부분을 인지하고 그 부분만 재렌더링한다.
useState
: state를 가지는 대상과 그 대상의 state를 변화시키는 함수를 생성
state를 생성할 때는 배열 안에 state 변수와 state 갱신 함수를 할당하고 useState로 초기 값을 설정한다. 또한, useState를 import해줘야 한다.
import { useState } from 'react'
const [state 변수, state 변수를 갱신하는 함수] = useState(초기값)
state는 읽기 전용이다. 따라서 state의 값을 변경할 때는 state 변수를 직접 변경하는 것이 아닌, setState 함수를 호출하여 변경한다.
const [count, setCount] = useState(0); // 초기값 0
setCount((current) => { // current : 현재 값
return current + 1 // 현재 값 + 1
})
state가 Object인 경우, Object 자체가 변경되어야 리액트가 변화를 인지할 수 있다. 때문에 Object를 새로운 Object로 복사한 후, 변경하고 싶은 값을 변경하고 새 Object를 리턴해야 한다.
const [user, setUser] = useState({name: '홍길동', age:20 })
setUser((current) => {
const newUser = { ...current } // 기존 Object를 newUser로 복사
newUser.age = 21 // newUser의 age값만 변경
return newUser // newUser 리턴
})
리액트의 생명주기는 컴포넌트가 이벤트를 다룰 수 있는 시점을 의미하며, Mount(생성)
, Update(업데이트)
, Unmount(제거)
로 구성된다.
라이프사이클 메서드
📌will
메서드 : 어떤 작업을 작동하기 전에 실행
📌Did
메서드 : 어떤 작업을 작동한 후에 실행
•constructor
: state 데이터 초기화, 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성 메소드
•render
: 준비한 UI를 렌더링, 클래스 컴포넌트에서 반드시 구현되어야 하는 메소드
•componentDidMount
: 컴포넌트가 마운트 된 직후 호출하는 메소드
•componentDidUpdate
: 컴포넌트의 업데이트 작업이 진행된 직후에 호출되는 메소드
•componentWillUnmount
: 컴포넌트가 언마운트 되어 제거되기 직전에 호출하는 메소드
•getDerivedStateFromProps
: props에 있는 값을 state에 넣거나, state r값에 변화를 주는 메소드
•shouldComponentUpdate
: 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정하는 메소드
•getSnapshotBeforeUpdate
: 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출하는 메소드
•componentDidCatch
: 에러가 발생했을 때 애플리케이션이 먹통이 되지 않고, 오류 UI를 보여 줄 수 있게하는 메소드
⭐ 요약
Props는 컴포넌트에 전달하는 값으로, 직접 수정 불가능하다
State는 컴포넌트 내부에서 선언되어 관리되는 값으로, 수정 가능하다.
Hooks
는 컴포넌트에서 데이터를 관리(State)하고 데이터가 변경될 때 상호작용(Effect)을 하기 위해 사용한다. Hooks가 도입됨으로써 함수형 컴포넌트에서도 상태 관리를 할 수 있게 되었다. 클래스 컴포넌트로 구현해야 했던 것들을 함수형 컴포넌트에서 더 간편하게 구현할 수 있게 되었고 그 결과로 함수형 컴포넌트의 사용이 증가했다.
• Hook명은 use
로 시작하며 앞서 살펴본 useState
도 Hook이다.
• Hook은 React 함수내에서만 사용이 가능하다.
• 최상위 레벨에서만 Hook을 호출할 수 있다. 즉, 가장 바깥쪽 {중괄호}안에서 호출되어야 한다는 것이다. (for문, if문, 콜백함수 등 X)
useState는 앞서 살펴보았기 때문에 간단하게만 짚고 넘어가도록 하겠다.
useState를 호출하면 배열이 반환된다. 그 첫번째 인덱스는 state이름, 두번째 인덱스는 setState 이름이다. 따라서 useState를 사용하려면 배열에 두 가지를 선언해야 한다.
import { useState } from 'react'
const [state이름, setState이름] = useState(초기값)
const App = () => {
const [name, setName] = useState("홍길동")
setName("신짱구")
}
useEffect
를 사용하면 함수 컴포넌트에서 side effect를 수행할 수 있다. (특정 부분이 바뀔 때마다 부수적으로 다른 부분도 함께 변화되는 효과)
import { useEffect } from 'react'
useEffect(실행될 콜백 함수, [변화를 감지할 대상(state/props)])
[감지 대상1, 감지 대상2, ...]
[빈배열]
을 넘겨주면 된다.import React, {useState, useEffect} from "react";
const App = () => {
const [name, setName] = useState("신짱구");
// name을 수정할 때마다 console을 찍음
useEffect(() => {
console.log(`이름이 ${name}으로 변경 되었습니다.`)
}, [name])
// input에 입력된 값으로 내용 변경
return (
<div>
<input onChange={
(event) => setName(event.target.value)
} value={name} />
<p>{name}님 안녕하세요.</p>
</div>
)
}
useMemo
를 사용하면 함수형 컴포넌트 내부에서 발생하는 연산을 최적화할 수 있다.
지정한 대상인 State나 Props가 변경될 경우 해당 값을 활용해 계산된 값을 메모이제이션하여 재렌더링 시 불필요한 연산을 줄인다. 사용하는 형태는 useEffect와 비슷하다.
import { useMemo } from 'react'
useMemo(실행될 콜백 함수, [변화를 감지할 대상(state/props)])
useCallback
은 useMemo와 비슷하다. 함수를 메모이제이션하기 위해 사용한다. 컴포넌트가 재렌더링될 때 불필요하게 함수가 재생성되는 것을 방지하기 때문에 주로 렌더링 성능을 최적화해야 할 때 사용한다.
import { useCallback } from 'react'
useCallback(실행될 콜백 함수, [변화를 감지할 대상(state/props)])
❗따라서
useMemo(() => 콜백 함수, 감지 대상)
과
useCallback(콜백 함수, 감지 대상)
는 같다.
useRef
는 함수형 컴포넌트에서 ref를 쉽게 사용할 수 있게 해준다. 컴포넌트 생애 주기 내에서 유지할 ref 객체를 반환하며, ref 객체는 .current
라는 프로퍼티를 가진다. ref 객체가 변경되어도 컴포넌트가 재렌더링되지 않는다.
import { useRef } from 'react'
useRef(initialValue)
• 리액트에서의 이벤트는 camel case로 작성한다.
• 자체적으로 생성한 컴포넌트에는 이벤트를 적용할 수 없으며, DOM 요소(<div>, <p>, <input> 등
)에만 이벤트를 적용할 수 있다.
• 이벤트 핸들링은 함수의 형태로 넘겨준다. 따라서, 자바스크립트이기 때문에 {중괄호}
에 담아서 전달한다.
• 이벤트가 발생한 요소는 event.target
으로, 그 요소의 값은 event.target.value
로 받아온다.
리액트에서의 이벤트는 자바스크립트와 비슷하지만 역시 camel case로 작성하기 때문에 이벤트명들이 약간의 차이가 있다. 자주 사용되는 이벤트는 다음과 같다.
onClick
: 요소가 클릭되었을 때
onDoubleClick
: 요소를 더블 클릭했을 때
onKeyDown
, onKeyUp
, onKeyPress
: 키보드 입력이 발생했을 때
onChange
: 요소의 값이 변경되었을 때
onFocus
: 요소에 포커스가 이동되었을 때
onBlur
: 요소에 포커스가 벗어났을 때
onSubmit
: Form 요소에서 Submit되었을 때
React에서 이벤트를 처리하는 방법은 두 가지가 있다.
① 익명 함수로 처리하기 onClick={() => {이벤트 내용}}
const App = () => {
return (
<div>
<button onClick={() => {
alert('클릭!');
}}>Click!!</button>
</div>
)
}
② 핸들링 함수 선언하기 onClick={이벤트핸들링함수명}
const App = () => {
const clickEvent = () => {
alert("클릭!");
}
return (
<div>
<button onClick={clickEvent}>Click!!</button>
</div>
);
};
import React, {useState} from 'react';
function App() {
// state 생성
// name(state 변수), setName(이름 변경 함수), useState(초기값은 홍길동)
const [name, setName] = useState("홍길동");
// 이벤트 핸들링 함수
// 이벤트가 발생한 요소에서 입력된 값(이름)을 가져오고 해당 값으로 name 변경(setState)
function handleInput(event) {
setName(event.target.value)
}
return (
// input의 값이 변경되었을 때 handleInput 이벤트 핸들링
// 기본값으로 name 설정, 출력값은 <이름>님 반갑습니다.
<div className="App">
<input onChange={handleInput} defaultValue={name} />
<span>{name}님 반갑습니다.</span>
</div>
);
}
참고자료
🐰 엘리스 SW 엔지니어 트랙 2기
📑 React 공식 문서
📑 컴포넌트 생명주기 메서드
📑 리액트의 Hooks 완벽 정복하기