클래스 컴포넌트에서만 사용할 수 있던 상태관리와 라이프 사이클 관리를 함수 컴포넌트에도 사용할 수 있도록 연동해주는 함수.
미리 만들어둔 함수를 가져와서 사용하는 것이라서 Hook이라는 이름을 사용함.
리액트 초창기에는 class 컴포만 사용할 수 있는 기능들이 있어 클래스 컴포만 사용했음.
하지만 클래스컴포에 비해 함수컴포가 직관적이고 선언하기도 편하기 때문에 함수 컴포의 선호도가 증가하여 상태관리와 라이프사이클관리 기능을 함수컴포에서도 사용하고자 hook이 등장 함.
함수 컴포넌트에서만 사용이 가능하다.
hook의 이름은 use-로 시작함.
내장 hookdㅣ 존재(useState, useEffect, ...)
직접 hook을 만드는 것도 가능함(custom hook)
Hook은 함수 컴포넌트 or custom hook 안에서만 호출 가능.
Hook은 함수 컴포넌트 내의 최상위에서만 호출해야 함.(반복문, 조건문에서는 호출 ㄴㄴ)
: 최상위 - 함수 컴포넌트의 첫번째 중괄호 내부
-----Good
import React, { useState } from 'react';
const Test = () => {
const [color, setColor] = useState('red');
if (5 > 3) {
console.log('true');
}
return <div>Hello!</div>;
};
----Bad(error)
const Test = () => {
if (5 > 3) {
const [color, setColor] = useState('red');
}
return <div>Hello!</div>;
};
컴포넌트의 속성값
: 부모컴포넌트로부터 전달받은 데이터를 지니고 있는 객체
전달하고자 하는 어떤 값이든 자식 컴포넌트에 전달 가능.
:string, number, variable, function
------부모 컴포넌트--------
const Parent = () => {
const animal = '호랑이';
const testConsole = () => {
console.log('테스트 입니다.');
};
return (
<>
<h1>부모 컴포넌트입니다.</h1>
<p>{animal}</p>
<Child pet={animal} englishName="tiger" test={testConsole} />
<button onClick={testConsole}>클릭</button>
</>
);
};
---------자식 컴포넌트----------
const Child = (props) => {
console.log(props);
// {pet: '호랑이', englishName: 'tiger', test: testConsole()}
return (
<>
<h2>자식 컴포넌트입니다.</h2>
<p>{props.pet}</p> // 호랑이
<p>{props.englishName}</p> // tiger
<button onClick={props.test}>클릭</button>
</>
);
};
---------------이렇게 쓰면 eslint warning 안뜸---
const Child = ({pet, englishName, test}) => {
return (
<>
<h2>자식 컴포넌트입니다.</h2>
<p>{pet}</p> // 호랑이
<p>{englishName}</p> // tiger
<button onClick={test}>클릭</button>
</>
);
};
컴포넌트 내부에서 가지고 잇는 컴포의 상태값
:해당 컴포넌트가 UI에 보여줄 정보를 결정할 때 사용할 수 있는 상태값
컴포넌트 내에서 정의하고 사요하며 얼마든지 변경 가능.
import React, { useState } from 'react';
const Main = () => {
// 변수 color, setColor는 다름 이름으로 바뀔 수 있습니다.
let [color, setColor] = useState('red');
// color 변수의 초기값은 useState에 넣은 인자
// setColor는 첫번째 요소인 상태값을 업데이트하는 함수.
return (
<>
<h1 style={backgroundColor: color}>여기는 메인페이지입니다.</h1>
<button onClick={() => {setColor("blue")}}>배경색 변경</button>
// onClick 이벤트에 color= "blue"; 넣고 콘솔로 확인해보면
//color에 blue가 할당됨을 확인할 수 있지만 리렌더링 해주지 않기 때문에 화면 변화가 없음
//하지만 setColor를 이용하면 자동으로 리렌더링을 해주기 때문에 화면에 변화가 생김.
</>
};
export default Main;
Props
: 컴포넌트의 속성값 ( 부모 컴포로부터 전달받은 데이터를 지니고 있는 개체)
전달하고자 하는 어떤 값이든 자식 컴포넌트에 전달 가능.
State
: 컴포넌트 내부에서 가지고 있는 컴포넌트의 상태값
해당 컴포넌트가 UI에 보여줄 정볼르 결정할 때 사용할 수 있는 상태값
컴포넌트 내에서 정의, 사용하며 얼마든지 변경 가능.
// Parent.js (부모 컴포넌트)
import React, { useState } from 'react';
import Child from './Child';
const Parent = () => {
const [color, setColor] = useState('red');
const changeColor = () => {
setColor('blue');
};
return (
<>
<div>부모 컴포넌트입니다.</div>
<Child color={color} change={changeColor} />
</>
);
};
export default Parent;
// Child.js (자식 컴포넌트)
import React from 'react';
const Child = (props) => {
console.log(props); // {color: 'red', change: () => {setColor('blue')}}
return (
<>
<div>자식 컴포넌트입니다.</div>
<p>{props.color}</p>
<button onClick={props.change}>색상 바꾸기</button>
</>
);
};
export default Child;
구조 분해 할당
이란 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 Javascript 표현식입니다. 아래의 예시를 통해 더 자세히 알아보겠습니다.
const animals = ["호랑이", "사자"];
console.log(animals[0]); // "호랑이"
console.log(animals[1]); // "사자"
const [tiger, lion] = ["호랑이", "사자"];
console.log(tiger); // "호랑이"
console.log(lion); // "사자"
animals라는 배열 안에는 “호랑이”, “사자”라는 문자열이 있습니다. 여기서 각각의 요소를 출력하고자 한다면 매번 animals[0], animals[1]과 같이 해당 배열의 몇 번째 요소라는 인덱스 값을 통해 접근해야 합니다.
하지만 여기서 배열에 구조 분해 할당을 적용한다면 animals의 첫 번째 요소인 “호랑이”를 변수 tiger에, 두 번째 요소인 “사자”를 변수 lion에 각각 할당할 수 있게 됩니다. 따라서, 매번 인덱스를 통해 배열의 요소에 접근하는 것이 아니라 할당된 변수를 통해 간단하게 배열의 요소를 불러올 수 있습니다.