작성
·
116
·
수정됨
1
안녕하세요. 소플님. 강의 정말 잘 듣고 있습니다.
컴포넌트 합성과 추출에서 props에 관련하여 질문이 있어 질문을 드립니다.
// Component 추출 전
function Comment(props){
return (
<div className = "comment">
<div className = "user-info">
<img className = "avatar"
src = {props.author.avatarUrl},
alt = {props.author.name}
/>
<div className = "user-info-name">
{props.author.name}
</div>
</div>
<div className = "comment-text">
{props.text}
</div>
<div className = "comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
첫 코드가 Component를 추출하기 전의 코드이고
/* Component 추출 후 */
// 1. Avatar Component 추출
function Avatar(props){
return(
<img className = "avatar"
src = {props.user.avatarUrl},
alt = {props.user.name}
{/* 재사용성을 측면을 높이기 위해 보편적인 단어인 user를 사용 */}
/>
);
}
// 2. UserInfoName Component 추출
function UserInfoName(props){
return(
<div className = "user-info-name">
{props.user.name}
</div>
);
}
// 3. UserInfo 추출하기
function UserInfo(props){
return(
<div className = "user-info">
{/* 이미 추출한 Avatar Component도 적용 */}
<Avatar user = {props.user} />
{/* 이미 추출한 UserInfoName Component도 적용 */}
<UserInfoName user = {props.user}/>
</div>
);
}
// 4. CommentText 추출하기
function CommentText(props){
return(
<div className = "comment-text">
{props.text}
</div>
);
}
// 5. CommentDate 추출하기
function CommentDate(props){
return(
<div className = "comment-date">
{formatDate(props.date)}
</div>
);
}
// 6. 추출한 Component들로 Comment 재합성
function Comment(props){
return(
<div className = "comment">
<UserInfo user = {props.user}/>
<CommentText text = {props.text}/>
<CommentDate date = {props.date}/>
</div>
);
}
이 코드가 강의에서 작성해주신 코드를 제 나름대로 완성한 컴포넌트를 추출한 형태입니다.
userData가 아래의 형태라고 가정하겠습니다.
const commentData = {
user: {
avatarUrl: "https://example.com/avatar.jpg", // 아바타 이미지 URL
name: "Soaple" // 사용자 이름
},
text: "안녕 리액트!",
date: new Date() // 댓글 작성 날짜
};
처음 Comment Component에 Props로는 CommentData 자체가 전달될 것이고, 그 다음 UserInfo의 props로는 props.user, 여기서는 아래의 commentData.user가 전달이 되는 것까지는 논리적 흐름대로 이해를 했습니다.
// UserInfo가 받은 props(commentData.user)
user: {
avatarUrl: "https://example.com/avatar.jpg",
name: "Soaple"
}
그런데 Avatar의 props로는 props.user가 전달되어야 하는데 그렇게 되면 Avatar에 전달하는 props가 commentData.user.user가 되어 전달할 수 없지 않나요? UserInfoName도 commentData.user.user가 되어 이상하다는 생각이 드는데... chatGPT나 뤼튼과 AI에 물어봐도 이상이 없는 정상 코드라는 답변을 받았습니다. React에서 props가 굉장히 중요하다고 강조하신 만큼 이 부분은 꼭 집고 넘어가야겠다는 생각이 듭니다. 답변 부탁드립니다!
답변 1
1
안녕하세요, 소플입니다.
우선 컴포넌트 추출에 대해서 깊게 고민해보신 부분이 굉장히 좋은 학습 방향인 것 같습니다.
질문해주신 부분에 대해서 답변을 드리면,
UserInfo
컴포넌트에 props.user
를 넘기게 되면 props
는 아래와 같은 형태가 됩니다.
props: {
user: {
avatarUrl: "https://example.com/avatar.jpg",
name: "Soaple"
}
}
그리고 이렇게 받은 props
에서 user
를 Avatar
컴포넌트에 user
라는 키값으로 넘기면,
Avatar
컴포넌트에 전달되는 props
도 동일하게 아래와 같은 형태가 됩니다.
props: {
user: {
avatarUrl: "https://example.com/avatar.jpg",
name: "Soaple"
}
}
그래서 결국 지금 작성하신 코드가 이상이 없다는 결론이 나오게 됩니다.
만약 계속 헷갈리신다면 아래와 같이 객체를 풀어서 써보시는 것도 쉽게 이해하기 위한 좋은 방법입니다.
function Comment(props) {
return (
<div className='comment'>
<UserInfo
user={{
avatarUrl: 'https://example.com/avatar.jpg',
name: 'Soaple',
}}
/>
<CommentText text={props.text} />
<CommentDate date={props.date} />
</div>
);
}
function UserInfo(props) {
return (
<div className='user-info'>
<Avatar
user={{
avatarUrl: 'https://example.com/avatar.jpg',
name: 'Soaple',
}}
/>
<UserInfoName
user={{
avatarUrl: 'https://example.com/avatar.jpg',
name: 'Soaple',
}}
/>
</div>
);
}
혹시 또 추가로 궁금한 점이 있다면 댓글 달아주시기 바랍니다!
감사합니다.
왜 props가 들어간 부분이 중괄호가 2개인가 고민을 좀 했는데 생각해보니 props는 JS객체(key-value 형태의 변수)이고 전달될 때 props 자체가 parameter로 전달되기 때문에 그렇네요!
귀한 시간 내주셔서 답변해주셔서 감사합니다.