인프런 커뮤니티 질문&답변

이지민님의 프로필 이미지
이지민

작성한 질문수

처음 만난 리액트(React)

컴포넌트 합성과 추출에서 props에 관해 질문이 있습니다!

작성

·

98

·

수정됨

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

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

안녕하세요, 소플입니다.

우선 컴포넌트 추출에 대해서 깊게 고민해보신 부분이 굉장히 좋은 학습 방향인 것 같습니다.

 

질문해주신 부분에 대해서 답변을 드리면,

UserInfo 컴포넌트에 props.user를 넘기게 되면 props는 아래와 같은 형태가 됩니다.

props: {
    user: {
        avatarUrl: "https://example.com/avatar.jpg",
        name: "Soaple"
    }
}

그리고 이렇게 받은 props에서 userAvatar 컴포넌트에 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로 전달되기 때문에 그렇네요!

귀한 시간 내주셔서 답변해주셔서 감사합니다.

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

네, 지민님 잘 이해하신 것 같습니다ㅎㅎ

꼭 완강하시고 궁금한 점이 있다면 언제든지 또 질문 남겨주세요~!

이지민님의 프로필 이미지
이지민

작성한 질문수

질문하기