리액트로 본격적인 개발을 시작하기 전에 기본적인 내용들을 먼저 정리해볼까 한다.
이번 포스팅에서는 리액트를 사용할 때 알아둬야 할 암묵적인 규칙들을 컴포넌트, 스타일 적용, 그리고 Props 관점에서 살펴보려고 한다 👀
React 컴포넌트는 크게 2가지 종류로 나눌 수 있다.
컴포넌트 종류
- 클래스형 컴포넌트
- 함수형 컴포넌트
최근 리액트 개발에서는 함수형 컴포넌트를 주로 사용한다.
하지만 실제 프로젝트의 레거시 코드에서는 클래스형 컴포넌트를 마주칠 수 있다.
그래서 앞으로의 포스팅에서는 함수형 컴포넌트를 중심으로 설명하되, 클래스형 컴포넌트도 이해할 수 있도록 기본적인 내용을 함께 다룰 생각이다.
클래스형 컴포넌트는 react의 Components를 상속받아 작성한다.
상속을 통해 부모의 기능을 사용할 수 있고, 필요한 경우 오버라이딩으로 기능을 수정할 수도 있다.
주요 특징들을 코드와 함께 살펴보자!
1. render 메서드를 내부에 직접 정의 한다.
- Sample Code
import { Component } from "react"; class MyComponent extends Component { render() { return ( <div>Hello, React!</div> ); }
- 화면에 렌더링할 HTML 태그는 render 메서드 안의 return문에 정의해야 한다.
2. 속성과 메서드는 this를 통해 접근한다. (1)
- Sample Code
class MyComponent extends Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return <div>{this.state.count}</div>; } }
- 여기서 this는 생성된 컴포넌트 인스턴스를 의미한다.
- 컴포넌트 내부에서 선언된 내용에 접근하려면 this를 통해서 접근해야 한다.
2. 속성과 메서드는 this를 통해 접근한다. (2)
- Sample Code
// App.jsx import MyComponent from "./MyComponent"; function App() { return <MyComponent color="검정색" />; } export default App;
// MyComponent const { Component } = require("react"); class MyComponent extends Component { render() { console.log(this); // this 로깅 return <div>{this.props.color}</div>; // 사용 예시 } } export default MyComponent;
- Console View
- 콘솔에 로그를 찍었을 때 화면처럼 Props에 값이 들어오는 것을 확인할 수 있다.
- 따라서 this.props로 접근하여 값을 사용할 수 있다.
이처럼 클래스형 컴포넌트의 경우, 상속하고 있는 Component가 컴포넌트를 만들기 위한 내부 동작을 모두 처리하고 있다.
this는 인스턴스 객체를 의미하므로 클래스형 컴포넌트를 사용할 때는 this를 통해 접근해서 사용하기만 하면 된다!
함수형 컴포넌트는 명시적으로 상속받는 객체는 없다.
몇가지 주요 특징을 살펴보자
1. 함수 선언문으로 작성한다.
- Sample Code
// 가장 기본적인 형태 function MyComponent() { return <div>Hello</div>; } // 화살표 함수 사용 const MyComponent = () => { return <div>Hello</div>; }
- 일반적인 JavaScript 함수처럼 작성하고, return문에 렌더링할 HTML 요소를 반환하면 된다.
2. Props처리 방식
- Sample Code
// 일반적인 형태 function MyComponent(props) { return <div>{props.name}</div>; } // 구조 분해 할당 사용 function MyComponent({ name, age }) { return ( <div> {name} ({age}) </div> ); }
- 이처럼 함수의 매개변수로 props를 받아서 사용할 수 있다.
3. Hooks를 사용하여 상태를 관리
- Sample Code
function MyComponent() { const [count, setCount] = useState(0); useEffect(() => { ... }, []); return <div>Count: {count}</div>; }
- use로 시작하는 훅을 사용해서 상태를 관리한다.
아무래도 함수형 컴포넌트로 작성된 코드가 더 간결하기 때문에 이해하기 쉽고
Hooks를 사용한 직관적인 상태관리가 용이하다.
만약 리액트를 처음 다룬다면 위 코드가 이해되지 않을 수 있는데,
만약 그렇다면 그냥 천천히 읽고 지금은 넘기도록 하자!
(어차피 보다보면 익숙해지니까...)
(따라서 앞으로는 살펴볼 주요 예시는 함수형 컴포넌트로 작성할 예정이다!)
React에서 스타일을 적용할 때는 객체 형태로 작성해야한다.
일반적으로 사용하는 규칙이 있는데, 스타일 속성은 카멜케이스(camelCase)로 작성하고, 숫자형 값의 경우 단위를 생략하면 자동으로 'px'가 적용된다.
간단한 예시 코드를 살펴보자.
인라인으로 스타일을 적용할 때는 객체로 CSS 스타일을 정의해서 넘겨주면 된다.
Example
function App() { return ( <h1 style={{ backgroundColor: "black", color: "yellow", fontSize: 28, padding: '16px' }}> 안녕하세요! </h1> ); }
당연히 스타일을 분리해서 관리할 수 있다.
(이전 포스팅 CSS에 대하여 (1) 에서 작성했던 내용과 맥락이 일치한다.)
Example
function App() { const myStyle = { backgroundColor: "black", color: "yellow", fontSize: 28, padding: '16px' }; return ( <h1 style={myStyle}>안녕하세요!</h1> ); }
CSS 파일을 사용할 때, 한 가지 특징은 className이라는 속성으로
class 이름을 정의하고 셀렉팅으로 스타일을 지정할 수 있다는 것이다.
Example
// App.css .react { background-color: black; color: yellow; font-size: 40px; padding: 10px; }
// App.js import "./App.css"; function App() { return ( <div className="react">안녕하세요!</div> ); }
위 예제에서도 이미 살펴봤지만, props는 컴포넌트에 전달되는 속성값을 의미한다.
Props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때 사용한다.
(같은 Props를 받더라도 클래스형과 함수형에서는 사용법이 좀 다르다)
(복습하는 느낌으로 보면 좋을 것 같다 👀)
부모 컴포넌트에서 MyComponent로 Props를 전달하고 있다.
이 때, 다르게 정의된 자식 컴포넌트에서는 props를 어떻게 사용하는지 살펴보자.
Example
// 부모 컴포넌트 function App() { return ( <MyComponent name="홍길동" age={23} nickname="길동이" /> ); }
// 자식 컴포넌트 - 클래스형 class MyComponent extends Component { render() { const { name, age, nickname } = this.props; return ( <> <h1>이름: {name}</h1> <h2>나이: {age}</h2> <h2>별명: {nickname}</h2> </> ); } }
// 자식 컴포넌트 - 함수형 function MyComponent({ name, age, nickname }) { return ( <> <h1>이름: {name}</h1> <h2>나이: {age}</h2> <h2>별명: {nickname}</h2> </> ); }
리액트에서는 Props가 전달되지 않을 경우 사용할 기본값을 설정할 수 있다.
Example
// 클래스형 컴포넌트 MyComponent.defaultProps = { name: "이름없음", age: 0, nickname: "별명없음" };
// 함수형 컴포넌트 - 매개변수 기본값 사용 function MyComponent({ name = "이름없음", age = 0, nickname = "별명없음" }) { return ( // ... ); }
클래스형 컴포넌트의 경우, 위처럼 defaultProps를 별도로 저장해주면 된다.
반면, 함수형 컴포넌트의 경우에는 props를 받는 곳에서 직접 정의하여 사용한다는 특징이 있다!
이렇게 React의 기본적인 컴포넌트 작성법과 props 사용법에 대해 살펴보았다.
리액트의 진짜 강점은 이런 컴포넌트들을 조합해서 복잡한 UI를 만들 수 있다는 점인데, 이번 포스팅에서는 아주 얇게 리액트를 훑어봤다.
이제부터 이어지는 포스팅에서는 리액트의 핵심 개념들을 더 자세히 파헤쳐볼 생각이다 👊