<div id="root"></div>
    <script type="text/babel">
        /* state
        state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다. 
        props는 부모 컴포넌트가 설정하는 값이지만, state는 컴포넌트 내부에서 설정되는 값이다. 
        props는 읽기 전용으로 사용되지만, state는 변경되는 값을 관리한다.

        클래스형 컴포넌트에서는 state를 직접 사용할 수 있다. 
        함수형 컴포넌트에서는 useState란 hooks로 별도로 기능을 제공하고 있다. 
        
        */

        class Counter extends React.Component {

            /* 컴포넌트를 생성할 때 가장 먼저 호출 되는 생성자 함수이다.  */
            constructor(props) {
                /* 부모 컴포넌트로부터 전달 받은 props를 부모 클래스의 생성자에 전달하면서 컴포넌트를 생성한다. */
                super(props);

                /* state를 초기화 한다. state는 생성자 안에서 초기화 하는 경우 this. 를 붙여야 한다. 
                또한 이름을 state로 작성해야 하며, state에 저장되는 값의 형태는 반드시 Object 리터럴 형태로 작성된다.*/
                this.state = {
                    number : 0
                };
            }
            render() {
                /* state에 저장된 number 상태 값을 구조분해할당을 이용해서 저장 */
                const { number } = this.state; //구조분해할당 
                
                /* state의 값을 변경하기 위해서는 setState 함수를 이용해야 한다. 
                새로운 상태 값을 가지고 있는 Object를 동일한 키로 설정하여 인자를 전달하면 state 객체를 덮어 쓰게 된다. 
                기존 state에 여러 값들이 있다고 해도 동일한 키를 가진 값만 덮어 쓰게 된다.  */
                return(
                    <>
                        <h1 style={ number < 0 ? { color : 'red' } : { color : 'blue' }}>Count : { number }</h1>
                        <button onClick={ () => this.setState({ number : number - 1 }) }>-1</button>
                        <button onClick={ () => this.setState({ number : number + 1 }) }>+1</button>
                        
                    </>
                )
            }
        }

        ReactDOM.createRoot(document.getElementById('root')).render(<Counter/>);
    </script>
       <div id="root"></div>
    <script type="text/babel">
        /* prevState를 활용한 setState 함수 사용
        this.setState를 사용할 시 상태가 변경되고 리랜더링이 되어야 state 값 변경이 적용된다. 
        하나의 이벤트 핸들러에서 여러 번 setState를 호출한다고 누적해서 갱신되지 않는다. 
        이 때 state 객체 대신 함수를 인자로 전달하여 첫번째 인자 prevState,
        두 번째 인자 props를 활용할 수 있다. 만약 props가 필요하지 않은 상황이면 생략 가능하다.
        
        */

        class Counter extends React.Component {

            /* 생성자 함수 없이 클래스의 속성으로 state를 추가하는 것도 가능하다.  
            이 때 this. 는 사용이 불가능하다. this. 은 인스턴스 생성 후 레퍼런스를
            보관할 변수이기 때문에 생성자 혹은 함수 내에서만 사용이 가능하다. */
            state = {
                number : 0
            }
        
            render() {
                /* state에 저장된 number 상태 값을 구조분해할당을 이용해서 저장 */
                const { number } = this.state; //구조분해할당 
                
                /* state의 값을 변경하기 위해서는 setState 함수를 이용해야 한다. 
                새로운 상태 값을 가지고 있는 Object를 동일한 키로 설정하여 인자를 전달하면 state 객체를 덮어 쓰게 된다. 
                기존 state에 여러 값들이 있다고 해도 동일한 키를 가진 값만 덮어 쓰게 된다.  */
                return(
                    <>
                        <h1 style={ number < 0 ? { color : 'red' } : { color : 'blue' }}>Count : { number }</h1>
                        <button onClick={ () => this.setState({ number : number - 1 }) }>-1</button>
                        <button onClick={ 
                            () => {
                                /* setState로 상태를 변경하지만 반영이 되어 있지는 않다. 
                                메모리에만 임시로 변경된 상태를 가지고 있으며
                                해당 함수가 종료되면 변경 내역을 반영한다. */
                                // console.log(`number : ${this.state.number}`); // 그 이전의 상태를 갖고 있고, 함수가 종료될 때 한번에 변경된다.
                                // this.setState({ number : number + 1 });
                                // console.log(`number : ${this.state.number}`);
                                // this.setState({ number : number + 1 });
                                // console.log(`number : ${this.state.number}`);

                                /* 이러한 상황을 해결하기 위해서는 prevState를 이용한다. */
                                this.setState((prevState, props) => {
                                    return {
                                        number : prevState.number + 1
                                    };
                                });

                                this.setState(prevState => ({ number : prevState.number + }));
                            } 
                        }
                        >+1</button>
                        
                    </>
                );
            }
        }

        ReactDOM.createRoot(document.getElementById('root')).render(<Counter/>);
    </script>
    <div id="root"></div>
    <script type="text/babel">
        /* setState 이후 특정 작업 실행하기 */

        class Light extends React.Component {

            state = {
                isOn : false
            };

            render() {

                const { isOn } = this.state;

                const style = {
                    width : 200,
                    height : 200,
                    backgroundColor : isOn ? 'green' : 'red',
                    transition : '2s'

                };

                return (
                    <>
                        <div style={style}></div>
                        <button onClick={
                            () => this.setState(
                                { isOn : !isOn }, //on이면 off, off였으면 on
                                () => console.log(isOn ? '불이 켜졌습니다' : '불이 꺼졌습니다')
                                ) 
                        }
                        >
                            { isOn? 'OFF' : 'ON'}
                        </button>
                    </>
                );
            }
        }

        ReactDOM.createRoot(document.getElementById('root')).render(<Light/>);
    </script>

 

'LECTURE > React' 카테고리의 다른 글

props  (0) 2023.04.17
React rendering  (0) 2023.04.17
[React] JSX intro, 표현법, Fragment, attribute, 주석 작성법  (0) 2023.04.17
[React] intro - createElement and render, history of component  (0) 2023.04.17

props

        properties의 약어로, 컴포넌트의 속성을 설정할 때 사용하는 요소이다. 
        props 값은 해당 컴포넌트를 사용하는 부모 컴포넌트에서 설정할 수 있다. 
        props는 읽기 전용이기 때문에 수정해서는 안된다.

<body>
    <div id="root"></div>
    <script type="text/babel">

        function Title(props) {
            return <h1> 안녕하세요 { props.name }님, 환영합니다.</h1>;
        }

        /* props.name이 존재하지 않을 경우의 기본 값 설정 */
        Title.defaultProps = {
            name : '아무개'
        }

        const name1 = "홍길동";
        const name2 = "유관순";

        ReactDOM.createRoot(document.getElementById('root')).render(
        [   
            <Title name={ name1 }/>,
            <Title name={ name2 }/>,
            <Title name=" 이순신 "/>,
            <Title/>
        
        ] 
        );

    </script>

 

children-props

<body>
    <div id="root"></div>
    <script type="text/babel">

        function ChilerenNodePrinter(props) {

            console.log(props);

            return(
                <>
                    <h1>자식 노드가 가지고 있는 값은?</h1>
                    <h3>children : <font style={ {color : 'orange'} }>{ props.children }</font></h3>
                </>
            );
        }

        ReactDOM.createRoot(document.getElementById('root')).render(
           [
                <ChilerenNodePrinter name="홍길동" phone="010-1234-5678">텍스트노드</ChilerenNodePrinter>,
                <ChilerenNodePrinter><div>자식노드</div></ChilerenNodePrinter>,
                <ChilerenNodePrinter><div>1</div><div>2</div><div>3</div></ChilerenNodePrinter>
           ] 
        );

    </script>

    
</body>

 

구조분해할당

S6에서 제공하는 구조분해할당 문법을 이용하여 props 객체 내부의 값을 바로 추출해서 사용할 수 있다.

(props. 를 생략하고 사용 가능하다)

1. 전달 받은 props 인자를 구조분해할당 하는 방법

         function PropsPrinter(props) {

             const { name, children } = props;

             return (
                 <>
                     <h1>제 이름은 { name }입니다. </h1>
                     <h3>제가 가지고 있는 children은 { children }입니다. </h3>
                 </>
             )
         }
         
         ReactDOM.createRoot(document.getElementById('root')).render(
        <PropsPrinter name ="홍길동">텍스트노드</PropsPrinter>
       );

 

2. 전달 받은 인자를 구조분해할당 하는 방법

           function PropsPrinter({ name, children}) {

                return (
                    <>
                        <h1>제 이름은 {name}입니다. </h1>
                        <h3>제가 가지고 있는 children은 {children}입니다. </h3>
                    </>
                )
            }

       ReactDOM.createRoot(document.getElementById('root')).render(
        <PropsPrinter name ="홍길동">텍스트노드</PropsPrinter>
       );

 

props-type-verify


        props의 타입이 잘못 되었다거나 필수 타입이 처리되지 않았음을 콘솔을 통해 알려준다. (랜더링이 되기는 함)

        필수적인 설정은 아니나 큰 규모의 프로젝트를 진행하거나 협업하게 되면 해당 컴포넌트에 어떤 props가 필요한지 
        쉽게 알 수 있어 개발 능률이 좋아질 수 있다. 

<body>
    <div id="root"></div>

    <script type="text/babel">

        function PropsVerify({ name, favoriteNumber, children }) {

            return (
                <>
                    <h1>제 이름은 { name } 입니다.</h1>
                    <h2>제가 좋아하는 숫자는 { favoriteNumber } 입니다.</h2>
                    <h3>제가 가지고 있는 children은 { children } 입니다.</h3>
                </>
            );
        }

        PropsVerify.propTypes = {
            name : PropTypes.string, 
            favoriteNumber : PropTypes.number.isRequired
        };

        ReactDOM.createRoot(document.getElementById('root')).render(
            [
                <PropsVerify name="홍길동" favoriteNumber={ 5 }>텍스트노드</PropsVerify>,
                <PropsVerify name={ 3 }>텍스트노드</PropsVerify> 
                // name숫자 전달, number 전달 안 함
            ]
        );

    </script>

</body>

 

'LECTURE > React' 카테고리의 다른 글

state  (0) 2023.04.18
React rendering  (0) 2023.04.17
[React] JSX intro, 표현법, Fragment, attribute, 주석 작성법  (0) 2023.04.17
[React] intro - createElement and render, history of component  (0) 2023.04.17

리액트 랜더링 

 아래 주석 안에 들어가는 모든 엘리먼트를 ReactDOM에서 관리하기 때문에 이것을 Root DOM node라고 부르다. 일반적으로 React로 구현된 애플리케이션은 하나의 루트 돔 노드가 있다.

  단, 리액트를 기존 앱에서 통합하려는 경우에는 원하는 만큼의 독립된 루트 돔 노드를 가질 수도 있다.

React Element를 루트 DOM 노드에 렌더링 하려면
        ReactDOM.createRoot(루트 DOM 노드).render(렌더링 할 엘리먼트)로 처리하면 된다.

<body>

    <div id="root"></div> <!-- 루트 돔 노드-->
    
    <script type="text/babel">

        const element = (
            <>
                <h1>What time is it now?</h1>
                <h3>It is { new Date().toLocaleTimeString() }</h3>
            </>
        );

        /* React Element를 루트 DOM 노드에 렌더링 하려면
        ReactDOM.createRoot(루트 DOM 노드).render(렌더링 할 엘리먼트)로 처리하면 된다. */
        ReactDOM.createRoot(document.getElementById('root')).render(element);

    </script>
</body>

 

리액트 엘리먼트는 불변 객체(immutable)이다.
        엘리먼트를 생성한 이후에는 해당 엘리먼트의 자식이나 속성을 변경할 수 없다.
        따라서 엘리먼트를 업데이트 하기 위해서는 완전히 새로운 엘리먼트를 만들고 다시 render를 호출해야 한다.

<body>

    <div id="root"></div> <!-- 루트 돔 노드-->
    
    <script type="text/babel">

        const ReactClientDOM = ReactDOM.createRoot(document.getElementById('root')); //한번만 일어나도록

        function tick() { //엘리먼트를 function 안에 작성, 이 함수를 1초에 한 번씩 부른다
            const element = (
            <>
                <h1>What time is it now?</h1>
                <h3>It is { new Date().toLocaleTimeString() }</h3>
            </>
             );

          ReactClientDOM.render(element); // element를 렌더링하는 동작은 초마다 일어나도록
       
        }

        tick(); //생성
        setInterval(tick, 1000); //1초에 한번씩 불러온다. 


    </script>


        1초 마다 tick 함수를 호출하여 새로운 엘리먼트를 생성하고 랜더링 한다.
        매 초마다 새로운 엘리먼트가 다시 랜더링 되지만 개발자 도구의 elements를 살펴보면
        실제 업데이트 되는 부분만 갱신 되는 것을 확인할 수 있다. 
        
        리액트 엘리먼트는 메모리 상에서 연산되는 가상의 돔으로, 실제 돔과 동일한 렌더 트리를 가지고 있다. (복제본)
        render 호출 시 새로운 렌더 트리를 만들고 가상의 돔과 비교 (diff 알고리즘) 후, 변화가 있는 부분만 실제 돔에 반영

          -> 돔에 대한 재구성을 많이 하지 않기 때문에 효율적이다

 

조건부 랜더링

  여러 개의 엘리먼트 중 특정 조건에 따라 하나의 엘리먼트만 랜더링 할 수 있다.  

<body>
    <div id="root"></div> 
    
    <script type="text/babel">
    
    const answer = parseInt(prompt('리액트가 재미 있으신가요? \n1. 재미있다. \n2. 어렵다.'));

    1. 랜더링 시 조건 비교 후 조건부 랜더링 

    const positiveElement = <h1>앞으로 점점 더 재밌어 질 거 예요^^</h1>
    const negativeElement = <h1>천천히 앞의 내용을 복습해보세요^^</h1>

    ReactDOM.createRoot(document.getElementById('root'))
        .render((answer==1) ? positiveElement : negativeElement);



     2. JSX 내에서 조건부로 엘리먼트 생성 (보편적)
     2-1. if문 

     let element;
     if(element === 1) {
         element = <h1>앞으로 점점 더 재밌어 질 거 예요^^</h1>;
     } else {
         element = <h1>천천히 앞의 내용을 복습해보세요^^</h1>;
    }
    
    ReactDOM.createRoot(document.getElementById('root')).render(element);



     2-2. 삼항연산자 (if 보다 많이 쓰인다)

     const element = (answer === 1) ? (
         <h1>앞으로 점점 더 재밌어 질 거 예요^^</h1>
     ) : (
         <h1>천천히 앞의 내용을 복습해보세요^^</h1>
     );
     ReactDOM.createRoot(document.getElementById('root')).render(element);



     2-3. && 연산자를 이용한 조건부 엘리먼트 생성
     특정 조건을 만족하는 경우에만 랜더링을 하고, 그렇지 않은 경우엔 아무것도 보이지 않게 하고자 할 때 사용한다. 

const element = answer === 1 && <h1>앞으로 점점 더 재밌어 질 거 예요^^</h1>;

 ReactDOM.createRoot(document.getElementById('root')).render(element);


     주의 사항
    false 조건을 가지고 랜더링을 하는 경우 조건에 일치하지 않으면 랜더링 되는 요소가 없지만

    0과 같이 falsy한 값을 이용해 조건부 엘리먼트 생성을 하면 판단은 false지만 0을 반환한다.  


    const number = 0;
    const element = number && <h1>0이 아닙니다</h1>;
    
    ReactDOM.createRoot(document.getElementById('root')).render(element);
    </script>
    
    
</body>

 

 

'LECTURE > React' 카테고리의 다른 글

state  (0) 2023.04.18
props  (0) 2023.04.17
[React] JSX intro, 표현법, Fragment, attribute, 주석 작성법  (0) 2023.04.17
[React] intro - createElement and render, history of component  (0) 2023.04.17

JSX


        createElement를 이용해 엘리먼트를 정의하면 복잡하고 가독성이 떨어진다.
        리액트 팀은 ReactElement를 정의하는 간단한 방법으로 JSX 문법을 제공하는데
        자바스크립트를 확장한 문법으로 ReactElement를 XML 문법 형식으로 정의할 수 있는 방법이다.

                                                                                     <key>value</key>

         단, JSX는 공식적인 자바스크립트 문법이 아니어서 바벨이라는 트랜스 컴파일링 툴이 필요하다.
        바벨은 ES6 + ES6 next 문법을 ES5 문법으로 변환해주는 도구인데
        JSX를 순수 리액트로 변환해주는 기능도 포함하고 있다. (바벨이 JSX 처리 표준이다.)

 

1. 바벨 CDN 추가

https://unpkg.com/ : cdn 경로 얻기 위한 사이트

unpkg.com/:package@:version/:file  : 다운 받는 경로 작성법

<script src='https://unpkg.com/@babel/standalone/babel.min.js'></script> : 바벨 CDN 추가

<!DOCTYPE html>
<html lang="kor">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>01_JSX-intro </title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src='https://unpkg.com/@babel/standalone/babel.min.js'></script>
</head>

 

2. script 태그의 type 속성 추가 : <script type = "text/babel">

<body>

    <div id="root"></div>

    <script type = "text/babel">
        const helloWord = <h1>Hello World!</h1>;

        ReactDOM.createRoot(document.getElementById('root')).render(helloWord);

    </script>
    
</body>
</html>

JSX문법은 html 문법과 비슷하지만 차이점이 있다.

 

JSX 표현법

JSX 문법 내에 중괄호를 이용하여 모든 javascript 표현식(문법)을 넣을 수 있다.

<body>
    <div id="root"></div>

    <script type="text/babel">

        function formatName(user) { //user라는 객체를 받아서 lastName과 firstName을 반환한다.

            return `${user.lastName} ${user.firstName}`;
        }

        const user = {
            firstName : 'Gilldong',
            lastName : 'Hong'
        };

        /* JSX 문법 내에 중괄호를 이용하여 모든 javascript 표현식(문법)을 넣을 수 있다. */
        const element = <h1>Hello, { formatName(user) }</h1>

        ReactDOM.createRoot(document.getElementById('root')).render(element);

    </script>
    
</body>

 

Fragment

<body>
    <div id="root"></div>
    
    <script type="text/babel">
        
        const user = {
            name : 'Gildong',
            phone : '010-1234-5678'
        };

		- 아래 내용 -
	
        ReactDOM.createRoot(document.getElementById('root')).render(element);
    </script>
</body>

       

 1.최상위 엘리먼트가 두 개 이상이면 에러가 발생한다 -> 하나의 돔 트리만 생성해야 한다. 형제 노드 X

        const element = (
            <h1>Hello, { user.name }</h1>
            <h3>phone : { user.phone}</h3>
        ); -> 에러 발생



      2. <div> 태그로 감싸서 하나의 돔 트리를 생성할 수 있도록 한다. -> 불필요한 div 태그가 생성된다.

        const element = (
           <div>
                <h1>Hello, { user.name }</h1>
                <h3>phone : { user.phone}</h3>
            </div>
        );



   3. <React.Fragment>로 감싸서 형식상의 돔 트리상 상위 엘리먼트를 만들어 준다.

             const element = (
             <React.Fragment>
                 <h1>Hello, { user.name }</h1>
                 <h3>phone : { user.phone}</h3>
             </React.Fragment>
         );



    4. React 라이브러리로부터 Fragment 객체만 구조분해할당 해주면 React. 생략 가능하다. -> 미리 정의해서 사용

     const { Fragment } = React; // React의 기능 중에 Fragment를 꺼내서 사용할거야

     const element = (
             <Fragment>
                 <h1>Hello, { user.name }</h1>
                 <h3>phone : { user.phone}</h3>
             </Fragment>
         );



    5. React.Fragment의 축약 문법인 <></>로 감싸서 사용할 수 있다 (babel 17 부터 제공)

        const element = (
            <>
                <h1>Hello, { user.name }</h1>
                <h3>phone : { user.phone}</h3>
            </>
        );

 

attribute

JSX는 HTML 태그처럼 보이지만 실제로는 자바스크립트이다. (React.createElement를 호출하는 코드로 컴파일 된다.)
 따라서 자바스크립트의 예약어와 동일한 이름의 attribute는 다른 이름으로 우회적으로 사용하도록 정의되어 있다.

<head>
<style>
        .hightlight {
            background-color: red;
        }
    </style>

</head>
<body>
    
    <div id="root"></div>
    
    <script type="text/babel">

    
     1. 문자열로 속성 값 정의하는 방법 

    const element = <h1 id="title" className="hightlight">Hello World!</h1> 
    //id는 id, class는 className



     2. 자바스크립트 표현식을 이용하는 방법

    const id = "title"
    const className = "hightlight"
    const element = <h1 id={ id } className={ className }>Hello World!</h1>;

    ReactDOM.createRoot(document.getElementById('root')).render(element);
    
    </script>

</body>



inline style attribute

        style 속성에 객체 형태의 attribute를 추가해야 한다.
         객체의 속성명은 카멜 케이스로 작성한다. 
         속성 값은 문자열 혹은 숫자 형태로 작성해야한다.
   

<body>

    <div id="root"></div>

    <script type="text/babel">

        const style = {
            backgroundColor : 'black',  // 속성명(key) 카멜케이스, 속성값(value) 숫자 or 문자열
            color : 'white',
            cursor : 'pointer',
            textAlign : 'center',
            padding : 20
            // 단위를 작성하려면 문자열로 사용하지만('20px') 단위를 생략하면 숫자만 사용 가능
        };

        const element = (
            <>
                <h1 style={ style }>Hello World!</h1> //객체 형태의 어트리뷰트 추가
                <h3>inline styling test</h3>
            </>
        );

        ReactDOM.createRoot(document.getElementById('root')).render(element);

    </script>
    
</body>

 

event-attribute

<body>
    <div id="root"></div>
    
    <script type="text/babel">


        1. 인라인으로 간단한 이벤트 적용 시 JSX의 자바스크립트 표현식 내에  이벤트 처리 함수 작성 가능 
        

        const element = (
             <>
                 <h1>Event Attribute</h1> 
                 <button onClick={ () => alert('Hello World!') }>클릭하세요</button>
             </>
        );

-> html의 인라인 요소가 아니라 리액트로 처리하여 자바스크립트 코드로 컴파일 된다. 


        2. 이벤트 동작 시 사용할 핸들러 메소드 사전 정의 후 JSX 내에 표현식으로 사용 


        const onClickHandler = () => {
            alert('Hello World!');
        };

        const element = (
            <>
                <h1>Event Attribute</h1> 
                <button onClick={ onClickHandler }>클릭하세요</button>
            </>
        );

        ReactDOM.createRoot(document.getElementById('root')).render(element);
    </script>

</body>

-> 정의된 함수 onClickHandler를 onClick 에 전달한다.

 

JSX 주석 사용법

{/* 주석  작성*/}

개행 // 주석 작성

<body>
    <div id="root"></div>
    
    <script type="text/babel">

        const element = (
            <>
                <h1>Comment in JSX</h1>
                {/* JSX 내에서의 주석은 이렇게 작성합니다. */}    
                <h3
                    id="text"           //시작 태그를 여러 줄로 작성한다면 여기에도 주석 작성 가능 
                    className="text"
                >
                    JSX 내의 주석 사용하는 방법
                </h3>
                /*하지만 이런 주석이나*/
                //이런 주석은 페이지에 그대로 나타내게 됩니다.
            </>
        );
         
         ReactDOM.createRoot(document.getElementById('root')).render(element); //랜더링
   
   </script>

    
</body>

 

 

'LECTURE > React' 카테고리의 다른 글

state  (0) 2023.04.18
props  (0) 2023.04.17
React rendering  (0) 2023.04.17
[React] intro - createElement and render, history of component  (0) 2023.04.17

DOM

메모리 상에 존재하는 트리 형태의 객체 

노드(node)

요소 노드(테그) - 어트리뷰트 노드 - 텍스트 노드

 

React

JavaScript 라이브러리. 가장 큰 강점은 가상 돔을 사용하여 실제 DOM 업데이트의 성능 비용을 줄인다.

<!DOCTYPE html>
<html lang="kor">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>01_createElement-and-render</title>
    <!-- 리액트 공식 사이트의 문서에 웹 사이트 React 추가하기 메뉴의 cdn을 복사해서 넣어준다.-->
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
</head>

 

React.createElement를 사용해 h1 태그를 표현하는 엘리먼트를 만들 수 있다.
        첫 번째 인자 : 엘리먼트 타입을 문자열로 정의
        두 번째 인자 : 엘리먼트 프로퍼티 표현
        세 번째 인자 : 엘리먼트 자식 노드 표현 
        
        랜더린 과정에서 리액트는 이 엘리먼트를 실제 DOM 엘리먼트로 변환한다.
        <h1 id="greeting">hello world!</h1>

        리액트 엘리먼트는 단지 리액트에게 DOM 엘리먼트를 구성하는 방법을 알려주는 자바스크립트의 객체로
        실제 DOM 객체가 아니다. -> 따라서 DOM API랑 혼용하면 문제가 생긴다.

const greetingElement = React.createElement('h1', { id : 'greeting'}, 'hello world!'); //h1 태그, id 속성, 내부 텍스트
const textElement = React.createElement('h3', { id : 'name' }, '안녕하세요');

 

리액트 엘리먼트와 그 모든 자식 엘리먼트를 함께 랜더링하기 위한 함수
        첫 번째 인자 : 리액트 엘리먼트
        두 번째 인자 : 랜더링이 일어날 대상 DOM 노드 

ReactDOM.render(
             greetingElement,
             document.getElementById('root')  // 실제 삽입할 돔 노드
         );

 

16버전 이전의 엘리먼트는 한 엘리먼트만 랜더링 가능했지만, 이후 버전에서는 배열을 랜더링 할 수도 있다.

ReactDOM.render(
            [greetingElement, textElement],
             document.getElementById('root')
         );

 

18버전

ReactDOM.createRoot(document.getElementById('root')).render([greetingElement, textElement]);

 

컴포넌트

재사용이 가능한 단위

클래스 문법

ES2015(ES6)에 클래스 문법이 도입되면서 리액트에서도 리액트 컴포넌트를 클래스로 만드는 방법이 도입되었다.

    class helloWord extends React.Component {
        render() {
            return React.createElement(
                'h1',
                { className : 'greeting' },
                'Hello World!'
            );  
        }
    

    }
    ReactDOM.createRoot(document.getElementById('root')).render(
        React.createElement(helloWord)
    );

. React.Component를 상속하여 재사용이 가능한 클래스 형태의 컴포넌트이다.

render라는 메소드를 정의하면서 실제 랜더링하고 싶은 리액트의 엘리먼트를 최종적으로 반환한다.

반환된 값이 랜더링될 수 있도록 돔의 노드를 설정해서 만들고, 리액트의 createElement를 이용해서 반환된 값을 랜더링한다.

 

함수 기반 문법

현재도 class 구문을 사용해 리액트 컴포넌트를 만들 수 있지만 리액트 16버전부터 함수 기반의 컴포넌트를 생성하는 방법이 추가 되었고 현재 주를 이루고 있다.

    function HelloWorld() {

        return React.createElement('h1', { className : 'greeting' }, 'Hello World!');
    }

    ReactDOM.createRoot(document.getElementById('root')).render(
        React.createElement(HelloWorld)
    );

 

 

 

'LECTURE > React' 카테고리의 다른 글

state  (0) 2023.04.18
props  (0) 2023.04.17
React rendering  (0) 2023.04.17
[React] JSX intro, 표현법, Fragment, attribute, 주석 작성법  (0) 2023.04.17

+ Recent posts