ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [초심자 튜터링] React의 render() 리턴에 대하여
    React.js 2020. 11. 26. 02:04
    개인적으로 React를 소소히 튜터링하는 중인데, 튜터링하며 받는 질문에 대한 답변을 공유한다.
    초심자 기준이라 완전 초심자용 내용일수도.

    질문: React render에서 왜 에러가 나나요?

    질문 코드 예시

    class App from React.Component {
    	// 생략
        someFunction() {
        	return <p>someFunction</p>;
        }
        
        render() {
        	return (
            	<div>
                	<label>...생략...</label>
                </div>
                someFunction()
            );
        }
    }

    답변 1: JSX 구문 안에서 javascript 구문은 { }으로 감싸져야 합니다.

    여기서는 render함수의 return으로 "JSX 문법을 사용한 것" 반환하고 있습니다.

    그리고 <로 시작한 만큼 (아마도) return 괄호에 감싸진 전부를 React -> Javascript 변환시 JSX 부분이라고 생각할 겁니다.

    지금 이대로라면 (답변 2의 에러가 해결된다고 할 때) someFunction()은 문자 그대로 "someFunction()"으로 화면에 출력됩니다.

    javascript 함수라고 아무도 알지 못하기 때문이죠.

     

    React는 UI를 class 내부에서 쉽게 만들 수 있도록 JSX라는 system을 제공합니다.

    그리고 이 JSX는 plain javascript가 아니니, 브라우저에서 실행되기 위해서는 javascript로 변환되는 과정이 필요합니다.

    이렇게 React 프로젝트가 plain javascript (vanilla javascript 라고 합니다)로 변경될 때 거치는 과정을 (쉽게) 생각해보면,

    return 뒤에 뭐가 튀어나왔는지 보고 <div>로 시작하니 JSX라고 판단할테고,

    그 안에서 읽다가 또 다른 약속된 syntax(쉽게 문법)가 있어야만 JSX 안의 javascrtipt 코드를 프로세싱 할 수 있습니다.

    그렇지 않으면 그저 string이 될 뿐이죠.

     

    우리가 위의 someFunction을 실행시켜서 그 return 값을 someFunction() 자리에 끼워넣기 위해서는 위에 언급한 약속된 syntax가 필요합니다.

    그런 약속이 { } 입니다. 

    JSX 안에서 {로 시작하고 }로 끝나는 사이에 있는 것들은 javascript 코드로 생각하고 실행 시키자.

    그리고 그 실행의 결과를 대신 {...} 자리에 넣자. 이렇게요.

     

    열심히 짠 javascript 코드가 JSX 안에서 빛을 발하려면 꼭 컴퓨터에게 이거 js 코드야! string이 아니고! 라고 언질을 주시기 바랍니다.
    JSX 관련 문서 참고

    답변 2: render() 의 return값은 항상 한 덩어리여야 합니다.

    JSX 문법은 (얼핏 보면 html처럼 보이는) 실제 코드에서는 React Element로 치환됩니다.

    <https://ko.reactjs.org/docs/react-component.html#render>

    render() 메서드는 클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드입니다.

    이 메서드가 호출되면 this.props와 this.state의 값을 활용하여 아래의 것 중 하나를 반환해야 합니다.

    • React 엘리먼트. 보통 JSX를 사용하여 생성됩니다. 예를 들어, <div />와 <MyComponent />는 React가 DOM 노드 또는 사용자가 정의한 컴포넌트를 만들도록 지시하는 React 엘리먼트입니다.
    • 배열과 Fragment. render()를 통하여 여러 개의 엘리먼트를 반환합니다. 자세한 정보는 Fragments 문서를 통하여 확인할 수 있습니다.
    • Portal. 별도의 DOM 하위 트리에 자식 엘리먼트를 렌더링합니다. 자세한 정보는 Portals에서 확인할 수 있습니다.
    • 문자열과 숫자. 이 값들은 DOM 상에 텍스트 노드로서 렌더링됩니다.
    • Boolean 또는 null. 아무것도 렌더링하지 않습니다. (대부분의 경우 return test && <Child /> 패턴을 지원하는 데에 사용되며, 여기서 test는 boolean 값입니다.)

    React 공식문서에서 render 함수를 정의하는 것을 읽어보면 반드시 하나의 값만을 반환하도록 되어있죠.

    그러나 someFunction()의 반환을 render에 치환하게 되면 다음과 같은 결과가 됩니다.

    class App from React.Component {
    	// 생략
        someFunction() {
        	return <p>someFunction</p>;
        }
        
        render() {
        	return (
            	<div>
                	<label>...생략...</label>
                </div>
                <p>someFunction</p>
            );
        }
    }

    위 코드를 보면 return의 괄호로 감싸진 것이 한 덩어리가 아니게 됩니다. 그리고 이는 한 덩어리로 반환되지 않아서 에러를 발생시키죠.

    현재 div와 someFunction을 감싸는 무언가가 필요합니다. 보통은 제일 깔끔한? div로 감싸는 편입니다.

    div라는 불필요한 껍데기가 추가되는게 안좋아보이면 React Fragment를 검색해서 찾아보세요. (공식문서로 )

     

    참고) React Fragment는 금방 벗겨지는 임시 껍데기 같은 친구입니다. 

    render의 반환을 한덩어리 처럼 보이게 하지만, 실제로 화면에 렌더링 될 때에는 그 껍데기를 제외하고 그립니다.

    댓글

Designed by Tistory.