이번 포스팅에서는 함수 컴포넌트에 대한 개념에 대해 알아보고 이를 이용해 Counter 버튼을 만들어 보고자 한다. 우선 VSCode 터미널에서 npx create-react-app을 이용해 React app을 설치해주도록 하자. 그 후 npm run start를 이용해 React app을 실행시켜 제대로 설치가 되었는지 확인해보면 된다.
npx create-react-app [디렉토리명]
npm run start
< 목차 >
- 함수 컴포넌트
- props & children
- useState를 이용해 카운터 만들기
1. 함수 컴포넌트
함수 컴포넌트는 기존에 사용했던 클래스 컴포넌트와 다르게 함수를 이용해서 component를 생성한다. JavaScript에서 함수를 만들던 방식 그대로 함수를 만들어서 component를 만들어줄 수 있다. 단지 JSX 문법을 사용해서 return값을 만들어주기만 하면 된다. 코드를 살펴보도록 하자.
import React from 'react'
const Counter = () => {
return(
<div className='counter'>
<h1 className='header'>Hello React</h1>
<button className='btn'>버튼</button>
</div>
)
}
export default Counter;
위의 코드는 함수를 이용해 Counter라는 컴포넌트를 만들어 본 것이다. 함수 컴포넌트에서는 함수 자체가 클래스 컴포넌트의 render( )와 같은 역할을 수행한다. 그래서 export default로 함수 자체를 내보내기만 하면 된다. 클래스 컴포넌트와의 차이에 대해 조금 언급하자면 클래스 컴포넌트의 경우 상태가 변경되었을 때 render( ) 메소드 안에 있는 코드들만 다시 실행되는 반면 함수 컴포넌트는 상태가 변경되었을 때 함수 안에 있는 모든 코드들이 다시 실행된다. 따라서 함수 컴포넌트를 사용할 때에는 이 점에 유의하여 코드를 작성해야 한다.
위에서 작성된 Counter 함수의 return 값에 JSX를 이용해 만든 React 엘리먼트가 들어가 있는 것을 확인할 수 있다. 여기서 한가지 짚고 넘어가야할 사실은 return 값으로 들어간 React 엘리먼트들이 사실은 아래와 같은 객체라는 점이다.
{
type: 'div',
props: {
className: 'counter',
children: [
{
type: 'h1',
props: {
className: 'header'
}
},
{
type: 'button',
props: {
className: 'btn'
}
}
]
}
}
JSX도 결국엔 기존의 JavaScript를 확장한 문법에 지나지 않는다. return 값으로 나오게 되는 것이 위와 같은 객체들이라는 사실을 인지하고 있어야 하며 React에서는 이러한 객체를 이용해 엘리먼트들을 만들어주고 있었던 것이다. 쉽게말해 component를 만든다는 것은 React가 이해할 수 있는 객체를 만들어주는 것이라고 생각하면 된다.
이렇게 함수를 이용해 component를 생성했다면 클래스 컴포넌트에서와 마찬가지 방식으로 component를 호출해서 사용해주면 된다. 다음은 App.js 파일 안에서 위에서 생성한 Comment component를 사용한 예시이다.
import Counter from './Components/Counter.jsx'
function App() {
return (
<div>
<Counter />
</div>
);
}
export default App;
Counter component를 함수 형태로 생성했다고 해서 기존의 JavaScript에서 함수를 호출하는 방식인 Counter( )와 같이 component를 호출하는 것이 아닌 클래스 컴포넌트에서와 마찬가지로 <Counter /> 방식으로 호출하게 된다.
기존의 함수 컴포넌트에서는 클래스 컴포넌트에서처럼 상태를 만든다거나 생명주기를 다룰 수 없었다. 하지만 Hook이라는 개념이 등장했고 클래스 컴포넌트와 마찬가지로 상태를 만들고 컴포넌트의 생명주기를 다루는 등의 것들이 가능해졌다. 함수 컴포넌트에서 상태를 관리하거나 생명주기를 컨트롤 할 수 있도록 한 함수들을 Hook이라고 한다. Hook은 함수명이 use로 시작하는 특성을 가지고 있고 기본적으로 함수 컴포넌트 안에서만 작동된다. ( 클래스 컴포넌트에서 사용불가 ) Hook에 대한 소개는 여기까지 하기로 하고 보다 자세한 내용들은 다음 포스팅에서 다뤄보도록 하겠다.
2. props & children
함수 컴포넌트에서 props를 어떻게 전달하는지 알아보도록 하자. App.js 파일에서 위에서 생성한 Counter component에게 아래와 같이 props를 전달해 보았다.
import Counter from './Components/Counter.jsx'
function App() {
return (
<div>
<Counter value='여기가 props'>
여기가 children
</Counter>
</div>
);
}
export default App;
value라는 변수에 "여기가 props"라는 문자열을 넣어서 props를 전달했고 children에는 "여기가 children"이라는 텍스트를 작성했다. 이렇게 전달된 props와 children을 받기 위해서는 Counter component의 Counter 함수에서 props라는 매개변수를 이용해야 한다. 다음은 Counter 함수가 작성된 Counter.jsx 파일이다.
import React from 'react'
const Counter = (props) => {
return(
<div className='counter'>
<h1 className='header'>Hello React</h1>
<button className='btn'>버튼</button>
<h3>{props.value}</h3>
<h3>{props.children}</h3>
{console.log(props)}
</div>
)
}
export default Counter;
Counter 함수에서 props 매개변수를 이용해 props와 children을 전달 받게 된다. console.log( )를 이용해 브라우저에서 props를 출력해보면 다음과 같이 객체 형태로 전달받은 props와 children이 담겨 있는 것을 확인할 수 있다.
3. useState를 이용해 카운터 만들기
버튼을 클릭하면 값이 증가하는 간단한 카운터를 만들어보고자 한다. 이러한 카운터를 만들기 위해서는 우선 함수 컴포넌트에서 상태를 관리할 때 사용하는 useState 함수에 대해 알고 있어야 한다. 참고로 useState 함수가 바로 위에서 언급했던 Hook이다. 코드를 살펴보면서 useState( )에 대해 좀 더 알아보자.
import React, { useState } from 'react'
const Counter = () => {
const [count, setCount] = useState(0)
return(
<div className='counter'>
<h1>Counter</h1>
<h2>You clicked {count} times</h2>
<button onClick={()=>{ setCount( prev => prev + 1 ) }}>
Click me
</button>
</div>
)
}
export default Counter;
useState는 React에서 제공해주는 내장 Hook으로 state를 관리할 수 있도록 만들어진 함수이다. useState는 state 변수, 해당 변수를 갱신할 수 있는 함수 이 두가지 쌍을 반환한다. 다시말해, useState를 이용해 변수를 선언하면 2개의 아이템 쌍이 들어있는 배열로 만들어진다. 배열의 첫번째 요소는 현재 변수를 의미하고 두번째 요소는 해당 변수를 갱신해주는 함수이다. 따라서 아래와 같이 배열 구조 분해를 이용해 count라는 변수와 setCount라는 함수를 반환 받은 것이다. 여기서 count는 클래스 컴포넌트의 this.state.count , setCount 함수는 this.setState와 유사한 기능을 한다. 참고로 변수를 갱신해주는 함수는 클래스 컴포넌트의 this.setState와 거의 유사하지만 이전 state와 새로운 state를 합치지 않는다는 점에서 차이가 있다.
const [count, setCount] = useState(0)
이 때 useState( ) 함수의 인자값으로 들어가는 값은 상태를 관리할 변수에 들어갈 초기값이다. 위와 같은 경우 count 변수에는 0이 초기값으로 들어가게 되고 setCount 함수를 이용해 상태값을 변경할 수 있다.
우리가 만들어 볼 것은 버튼을 클릭했을 때 값이 증가하는 카운터이다. 따라서 <button>엘리먼트 안에 onClick 이벤트를 넣어 클릭이 발생했을 때 setCount( ) 함수가 실행돼 count 변수의 상태를 변경해주도록 하였다. 이 때 setCount 함수의 인자값으로 콜백함수를 집어 넣었는데 콜백의 첫번째 매개변수는 현재 상태값을 받게 된다. 상태를 바꾸기 이전의 값을 가져오고 싶은 경우 위와 같이 콜백함수를 사용해주면 된다.
완성된 최종 코드는 다음과 같다.
// App.js 파일
import Counter from './Components/Counter.jsx'
function App() {
return (
<div className='App'>
<Counter />
</div>
);
}
export default App;
// Counter.jsx 파일
import React, { useState } from 'react'
const Counter = () => {
const [count, setCount] = useState(0)
return(
<div className='counter'>
<h1>Counter</h1>
<h2>You clicked {count} times</h2>
<button onClick={()=>{ setCount( prev => prev + 1 ) }}>
Click me
</button>
</div>
)
}
export default Counter;
'React' 카테고리의 다른 글
React - useContext & useReducer (1) | 2022.04.29 |
---|---|
React - Lifecycle & useEffect (0) | 2022.04.26 |
create-react-app 없이 React 구동하기 (0) | 2022.04.21 |
React - css 적용하기 (0) | 2022.04.21 |
React - webpack.config.js (0) | 2022.04.20 |