드디어 리액트에서 가장 중요하고 가장 많이 쓰이는 state와 props개념에 대해서 정리해보려고 한다.
개념 자체는 그렇게 복잡하지 않았지만 배우고 나서 그래서 뭐 어쩌라고...? 🤷🏻♀️ 라는 생각이 들며 이 녀석들을 어떻게 활용해야할지 감이 잘 잡히지 않았다.
하지만...!! 한번 보고 다 알면 세상 사람들 다 개발자 했겠지..? 라는 생각을 하면서 나 자신을 위로하고 정신을 다시 바짝 차려서 state와 props의 개념을 정리하고 간단한 예제들도 살펴보고자 한다!
리액트 컴포넌트에 대해서 소개하면 함수 컴포넌트에서도 Hook의 등장으로 state나 lifeCycle등의 기능을 쓸 수 있다고 했다.
다시한번 정리하자면, Hook이란?
useState
useEffect
useNavigate
useRef
등)가 있으며 이런 hook들을 모음을 hooks 라고 한다. use
로 시작한다.useState
useEffect
)custom hook
💡 custom hook
- 컴포넌트 내에서 훅을 사용해 로직을 구현하다 보면 중복되는 부분이 발생하는데 이런 중복되는 훅들을 결합하고 추상화하고자하는 니즈가 발생한다. 이때 custom hook을 만들어 사용할 수 있다.
- custom hook은 Hook을 추상화된 로직으로 사용할 수 있도록 결합해주고 다른 컴포넌트 사이에서 공통의 상태 관련 로직을 재사용할 수 있도록 해준다.
공식문서 참고
<ComponentName prop1={propValue1} prop2={propValue2} ... />
형태로 컴포넌트를 부를 때 함께 지정한다. <Dog name="Ari" age={10} />
<Dog name="Bori" age={7} />
{}
로 값을 감싸야 한다.// <객체 인자를 통해 props 받아오기>
function Dog(props) {
consol.log(props)
//결과
//{name:'Ari', age:10}
//{name:'Bori', age:7}
return {
<div>{props.name}</div>
<div>{props.age}</div>
}
}
{ [인자 이름].[props 이름] }
형태로 사용한다.import {useState} from 'react'
로 import해야 사용이 가능하다.
배열로 반환한다.
const [name, setName] = useState();
name
setName
useState(초기값)
동일한 컴포넌트 안에 있더라고 state는 각각 관리된다.(다른 state에 영향을 미치지 않는다.)
import { useState } from 'react';
const Hello = () => {
const [name, nameChange] = useState('asj');
function chageName() {
const newName = name === 'asj' ? 'hdh' : 'asj';
nameChange(newName);
}
return (
<div>
<span>State</span>
<p>{name}</p>
<button onClick = {chageName}>Chane Name</button>
</div>
)
}
export default Hello;
react에서는 유동적인 데이터를 저장하기 위해서 state
를 이용한다. state
는 동적인 값 을 의미하는데, 직접 조작해서는 안되고 setState
를 이용 해야한다.
왜냐하면 react는 state
의 값이 변경되면 리렌더링을 해주는데 이때 setState
를 이용하지 않고 직접 바꾸게 되면 react가 변경된 state
를 감지하지 못하기 때문 이다.
//useState 기본구조
import {useState} from 'react';
const [state, setState] = useState('');
클릭 이벤트가 발생하면 counter되는 이벤트를 만들어보자.
//App.js
import React from 'react';
import Counter from './Counter';
const App = () => {
return (
<Counter />
);
}
export default App;
//Counter.js
import React from 'react';
const Counter = () => {
function OnIncrease() {
console.log('+1');
}
function OnDecrease() {
console.log('-1');
}
return (
<div>
<h1>0</h1>
<button onClick={OnIncrease}>+1</button>
<button onClick={OnDecrease}>-1</button>
</div>
);
}
export default Counter;
OnIncrease
에 설정을 해주었고, 감소 이벤트는 함수 OnDecrease
에 설정해주었다.button
의 onClick 으로 각 함수를 연결해주었다. 리액트에서 엘리먼트에 이벤트를 설정해줄때에는 on이벤트이름={실행하고싶은함수}
형태로 설정해주어야 한다.❗️ 주의할 점
이벤트 함수를onClick={onIncrease()}
이렇게 실행시키면안된다는 점이다. 이렇게 호출을 해주면 이벤트가 랜더링 되는 시점에 함수가 실행되기 때문에, (함수가 실행되면 리렌더링이 진행되되고 다시 함수가 실행되는 현상이 발생, state가 변경이 무한을 발생할 수 있음) 이벤트를 실행시킬때는 함수 타입의 값을 넣어주어야한다.
이제 위에서 설정한 이벤트의 동적인 값을 state
를 이용하여 상태관리가 될 수 있도록 작성해 보려고 한다.
//Counter.js
import React, { useState } from 'react';
const Counter = () => {
const [number, setNumber] = useState(0);
const onIncrease = () => {
setNumber(number + 1);
}
const onDecrease = () => {
setNumber(number - 1);
}
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
import React, { useState } from 'react';
useState
를 불러온다.const [number, setNumber] = useState(0);
원래는 아래와 같이 해야하지만 배열구조분해 를 사용하여 각 원소를 추출해준 것이다.
const numberState = useState(0);
const number = numberState[0];
const setNumber = numberState[1];
<h1>{number}</h1>
<h1>
안에 는 0이 아니라 {number}
를 넣어주면 되는데 이는 state를 변경해주는 함수(setNumber)에서 전달받은 최신 값을 반영해 준다.마무리✨
props와 state의 개념에 대해서 간단히 정리해 보았는데, 개념은 이해가 가지만 어떻게 활용할지는 직접 예제들을 접하고 간단한 프로젝트라고 만들어 보면서 해봐야 자연스럽게 쓸 수 있을 것 같다!
역시 코드는 손으로 직접 쳐보고 결과를 눈으로 직접 확인해봐야 이해가 잘 가는 것 같다~~