앞서 공부했던 내용들 중에 다양한 예시로 props를 사용했었다
props가 도대체 무엇이고 어떻게 사용하는지 이 글을 통해 알아보자.
리액트에서는 컴포넌트가 재사용 가능해야 하므로
특정한 값(데이터)을 외부에서 받아서 동적으로 다룰 수 있어야 한다.
이때 외부에서 값을 전달해주는 역할을 하는 것이 바로 props이다.
React props의 기본 개념
props (프로퍼티)는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방법이며
리액트에서는 컴포넌트 간에 데이터를 주고 받을 때
직접 값을 수정하는 것이 아니라,
props를 통해 데이터를 전달해 줘야한다.
만약 props없이 고정된 값이라면 다음과 같은 예시를 들 수 있다.
// Greeting.jsx
function Greeting() {
return (
<>
<h1>안녕하세요 섭이님</h1> {/* {name}이아닌 고정된 값 */}
</>
)
}
export default Greeting
// App.jsx
import Greeting from "./Greeting";
function App() {
return (
<>
<Greeting />
</>
)
}
export default App
이렇게 코드를 작성하개되면 항상 "섭이"라는 이름의 고정된 값이 출력된다
다른 이름을 표시하고 싶다 = 동적으로 표현하고 싶다 => props를 사용한다
props를 활용한 동적인 데이터 전달
위와 같이 고정된 값을 사용하지 않고
부모 컴포넌트에서 props를 전달하면 자식 컴포넌트에서 그 값을 사용할 수 있다.
// Greeting.jsx
function Greeting({ name }) {
return (
<>
<h1>안녕하세요 {name}님</h1>
</>
)
}
export default Greeting
// App.jsx
import Greeting from "./Greeting";
function App() {
return (
<>
<Greeting name="섭이" />
<Greeting name="행섭" />
</>
)
}
export default App
이렇게 같은 Greeting 컴포넌트를 여러번 사용해도 props를 통해 다른 값이 표시된다.
여러 개의 props 전달하기
props는 다음과 같이 여러 개를 한 번에 보낼 수 있다.
// Greeting.jsx
function Greeting({ name, age, job }) {
return (
<>
<h1>안녕하세요 {name}님</h1>
<p>나이: {age}</p>
<p>직업: {job}</p>
</>
)
}
export default Greeting
// App.jsx
import Greeting from "./Greeting";
function App() {
return (
<>
<Greeting name="섭이" age={20} job="백수" />
<Greeting name="행섭" age={21} job="비숍" />
</>
)
}
export default App
각 Greeting이 다른 props 값을 받아서 각각 다르게 표시된다.
props로 배열 & 객체 전달하기
props를 통해 배열이나 객체도 전달할 수 있다.
▶ 배열 전달 (map() 과 함께 사용)
// UserList.jsx
function UserList({ users }) {
return (
<ul>
{users.map((user, index) => (
<li key={index}>{user}</li>
))}
</ul>
);
}
export default UserList;
// App.jsx
import Greeting from "./Greeting";
import UserList from "./UserList";
function App() {
const UserNames = ['스기따라', '죡팡', '힝카인'] // props로 배열 전달
return (
<>
<Greeting name="섭이" age={20} job="백수" />
<Greeting name="행섭" age={21} job="비숍" />
<br />
<UserList users={UserNames} /> {/* 리스트 출력 */}
</>
)
}
export default App
위와 같이 배열을 map()을 사용하여 리스트로 출력할 수 있다.
▶ 객체 전달
객체를 props로 전달하면 코드가 더 깔끔해진다.
// profile.jsx
function Profile({ user }) {
return (
<>
<h2>{user.name}</h2>
<p>나이: {user.age}</p>
<p>직업: {user.job}</p>
</>
)
}
export default Profile
// App.jsx
import Greeting from "./Greeting";
import Profile from "./Profile";
import UserList from "./UserList";
function App() {
const UserNames = ['스기따라', '죡팡', '힝카인']
const userInfo = { name: "섭이", age: 20, job: "백수" } // props로 객체 전달
return (
<>
<Greeting name="섭이" age={20} job="백수" />
<Greeting name="행섭" age={21} job="비숍" />
<br />
<UserList users={UserNames} />
<br />
<Profile user={userInfo} /> {/* 리스트 출력 */}
</>
)
}
export default App
props 기본값 설정 하는 방법
props를 전달하지 않았을 때, 다음과 같이 기본값을 설정한다.
▶ || 연산자를 활용한 기본값 설정
// Greeting.jsx
function Greeting({ name, age, job }) {
return (
<>
<h1>안녕하세요 {name || "게스트"}님</h1>
<p>나이: {age || "정보가 없습니다."}</p>
<p>직업: {job || "정보가 없습니다."}</p>
</>
)
}
export default Greeting
name이 전달되지 않으면 "게스트" 가 기본값으로 사용된다.
// App.jsx
import Greeting from "./Greeting";
import Profile from "./Profile";
import UserList from "./UserList";
function App() {
const UserNames = ['스기따라', '죡팡', '힝카인']
const userInfo = { name: "섭이", age: 20, job: "백수" }
return (
<>
<Greeting /> {/* props 없이 사용 */}
<Greeting name="행섭" age={21} job="비숍" />
<br />
<UserList users={UserNames} />
<br />
<Profile user={userInfo} />
</>
)
}
export default App
propTypes로 데이터 타입 검사
지금까지 예제를 작성했을 때 props값을 넣으면
매번 'is missing in props validation' 오류가 발생한 것을 확인할 수 있었다.
그런데 이 오류가 생겨도 코드가 실행되지 않는 것은 아니라는 걸 직접 해봤기 때문에 알고 있을 텐데,
'props' is missing in props validation 오류는 개발 환경에서 코드 품질을 높이기 위한
ESLint의 경고이며 현재 props 유효성 검사가 설정되지 않아서 ESLint가 경고를 띄우는 것이다.
즉 컴포넌트에서 props를 받고 있지만
해당 prps 가 어떤 타입인지 명시하지 않았기 때문이다.
올바른 props 유효성 검사를 설정하면 오류 없이 더 안전한 코드를 작성할 수 있는데
해결 할 수 있는 두 가지 방법이 존재한다.
해결 방법 1: propTypes를 사용하여 유효성 검사 추가
propTypes를 사용하면 컴포넌트가 받을 props의 데이터 타입을 정의하고
필수 여부를 설정할 수 있다.
한번 propTypes를 적용해보자
▼ prop-types 라이브러리 설치
npm install prop-types
▼ propTypes 적용
// Greeting.jsx
import PropTypes from "prop-types"
function Greeting({ name, age, job }) {
return (
<>
<h1>안녕하세요 {name || "게스트"}님</h1>
<p>나이: {age || "정보가 없습니다."}</p>
<p>직업: {job || "정보가 없습니다."}</p>
</>
)
}
// propTypes
Greeting.propTypes = {
name: PropTypes.string, // name은 문자열 타입
age: PropTypes.number, // age는 숫자 타입
job: PropTypes.string, // job은 문자열 타입
}
export default Greeting
// Profile.jsx
import PropTypes from "prop-types"
function Profile({ user }) {
return (
<>
<h2>{user.name}</h2>
<p>나이: {user.age}</p>
<p>직업: {user.job}</p>
</>
)
}
Profile.propTypes = {
user: PropTypes.shape({ //
name: PropTypes.string.isRequired, // name은 필수 문자열
age: PropTypes.number, // age는 숫자 (필수 아님)
job: PropTypes.string, // job은 문자열 (필수 아님)
}).isRequired, // user 객체 자체가 필수
}
export default Profile
※ isRequired를 추가하면 필수값이 되며 누락시 ESLint 경고가 발생한다.
※ shape는 객체의 형태를 검사하는 역할을 하며 객체 내부의 각 속성까지 상세하게 타입을 검사한다.
// UserList.jsx
import PropTypes from "prop-types";
function UserList({ users }) {
return (
<ul>
{users.map((user, index) => (
<li key={index}>{user}</li>
))}
</ul>
);
}
// propTypes
UserList.propTypes = {
users: PropTypes.arrayOf(PropTypes.string).isRequired, // 배열 요소 검사
}
export default UserList;
※ arrayOf는 배열의 요소 타입을 검사하는 역할을 하며
배열을 받을 때, 배열의 각 요소가 올바른 타입인지 확인할 수 있다.
해결 방법 2: ESLint 설정에서 props validation 비활성화 (비추천)
이 방식은 props 유효성 검사를 완전히 끄는 것이므로 추천하지 않는다.
그래도 경고가 너무 신경쓰인다면 설정에서 비활성화를 할 수 있다.
settings.json에서 ESLint 설정을 변경하면 되는데
다음 설정을 추가하면 된다.
{
"rules": {
"react/prop-types": "off"
}
}
위와 같이 설정하면 props 유효성 검사를 하지 않기 때문에
경고 메세지가 더이상 나타나지는 않지만 props 오류를 쉽게 찾을 수 없기 때문에
사용하는 것을 추천하지 않는다.
결론은 propTypes는 리액트에서 props의 타입을 정의하고
props의 올바른 데이터 타입을 강제하여 실수를 방지하고 버그를 예방할 수 있다.
propTypes를 설정하면 잘못된 타입이 들어왔을 때 ESLint 경고가 발생하여
프로젝트에서 코드의 가독성과 유지 보수성이 높아진다.
'React' 카테고리의 다른 글
React - State (0) | 2025.02.26 |
---|---|
React - children props (0) | 2025.02.21 |
React - 리액트 컴포넌트 (React Component) (0) | 2025.02.19 |
React - JSX에서 자바스크립트 사용하기 (0) | 2025.02.17 |
React - 프래그먼트(Fragments) (0) | 2025.02.13 |