React 공식 홈페이지 따라하기

React 만들어보기 (5) - 함수 컴포넌트

vitamin3000 2025. 1. 27. 12:22

 

 

이번 시간에는 함수 컴포넌트에 대해 배워보고자 한다.

 

이전에 작성했던 vdom의 일부이다.

 

const vdom = 
<p>
    <h1> React 만들기</h1>
</p>

 

여기서 <h1> React 만들기 </h1>을 어떠한 이유로 함수로 변환하려 한다.

 

그러면 다음과 같이 작성할 수 있을 것이다.

function Title() {
    return <h1>제목</h1>
}

 

그렇다면 이것을 실제 호출할 때는 ? 

const vdom = <p>
    Title();
</p>

 

뭔가 어색하고, 한눈에 알아보기 힘들다.

자바스크립트는 JSX 문법을 지원하기에, JSX 문법으로 작성해보자

const vdom = <p>
    <Title/>;
</p>

 

이 코드를 실행하면 컴파일은 되지만, 오류가 발생한다. 

 

그 이유는 function Title은 JSX문법으로 작성되어 있고, 실제 JSX가 return 되는 것이 아니라 이전 포스트에서 알 수 있듯이 createElement의 함수 호출로 번들링되기 때문이다.

 

결과적으로 똑같지만 실행이 안되는 이유는 Title 함수가 호출이 되지 않기 때문(실제로 tag가 문자열로 처리되기 때문)이다.

 

그럼 babel을 통해 실제로 어떻게 변환이 되는지 확인해보자.

 

babel의 결과화면에서 app을 봐보자.

(원인) 인자 값으로 Hello가 문자가 아니라 코드인양 전달하고 있다.

(결과) 따라서 변수이므로 함수를 호출할 수 없어서 에러가 발생했던 것이다.

(해결방법) 그렇다면 변수를 함수로 변환한다면 정상적으로 처리될 것이다.

 

이러한 아이디어로 탄생한 것이..

변수 값이 대문자라면 문자열로 취급하지 않고 자바스크립트 값으로 취급하기로 정했다.

이때 값은 반드시 함수여야 하고 그 안에서 JSX를 return해야 한다.

 

그러면 createElement를 수정해보자!

아래 코드는 기존의 작성한 createElement 함수이다.

export function createElement(tag, props, ...children) {
    props = props || {};
    return { tag, props, children };
}

 

이것은 props가 객체로 되어있다.

 

수정한 코드는 다음과 같다.

조건문을 통해 함수인지를 검사하고, 맞다면 함수로 호출한다.

export function createElement(tag, props, ...children) {
    props = props || {};
    if (typeof tag === 'function')
    	return tag();
    return { tag, props, children };
}

 

그렇다면 Title도 수정해줘야겠죠?

 

function Title(props) {
    return <h1>{props.children}</h1>
}

 

하지만! 실제로 실행했을 때 오류를 발생한다

그 이유는 return tag()로 단순히 호출을 하고 있지 아무 값도 전달하고 있지 않기 때문이다.

 

다음과 같이 바꿔보자

    if (typeof tag === 'function')
    	return tag(props);

 

실행해보면? 여전히 안 된다

 

그 이유는 vdom 안에 JSX문법으로 작성한 Title이 children으로 들어간다는 보장이 없기 때문이다.

 

이렇게 수정해보자

    if (typeof tag === 'function')
   	{
  		if( children.length > 0
		{	
        	return tag({
            	...props,
                children:children.length === 1 ? children[0] : children.
 		})
        }else{
        	return tag(props);
        }
    }

 

단순한 만큼 한계점도 존재한다

예를 들어서 첫번째 문자가 대문자여야하고..