Class, Function Component

Hook 이전

  • 컴포넌트 내부에 상태가 있다면?
    • class 컴포넌트를 사용
  • 컴포넌트 내부에 상태가 없다면?
    • 라이프사이클을 사용해야하 한다면?
      • class 컴포넌트를 사용
    • 라이프사이클에 관계가 없다면?
      • function 컴포넌트를 사용

Class Component

import React from 'react';

// 정의
class ClassComponent extends React.Component{
	render(){
		return (<div>Hello</div>);
	}
}
// 사용
<ClassComponent/>

Function Component

import React from 'react'

// 정의1
function FunctionComponent(){
	return <div>Hello</div>
}

// 정의2
const FunctionComponent = () => <div>Hello</div>;

// 사용
<FunctionComponent />

React.createElement로 컴포넌트 만들기

<!-- ex5.html : React.createElement 로 컴포넌트를 만들기 -->
<!DOCTYPE html>
<html lang="en">
  <head>...</head>
  <body>
    <div id="root"></div>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script type="text/javascript">
	    React.createElement(
	        type, // 태그 이름 문자열 | React 컴포넌트 | React.Fragment
	        [props], // 리액트 컴포넌트에 넣어주는 데이터 객체
            [...children] // 자식으로 넣어주는 요소들
	    );

      // 1. 태그 이름 문자열 type
	    ReactDOM.render(
	        React.createElement('h1', null, `type 이 "태그 이름 문자열" 입니다.`),
	        document.querySelector('#root'),
	    );

      // 2. React 컴포넌트 type
	    const Component = props => {
	        return React.createElement('p', null, `type 이 "React 컴포넌트" 입니다.`);
	    };
	    // 결과
	    // <h1>type 이 "React 컴포넌트" 입니다.</h1>

        ReactDOM.render(
	        React.createElement(
		        Component,
		        null,
	            null
	        ),
	        document.querySelector("#root")
        );
        // 결과
        // <Component></Component/>

      // 3. React Fragment type
	    ReactDOM.render(
	        React.createElement(
	            React.Fragment,
	            null,
	            `type 이 "React Fragment" 입니다.`
	        ),
		    document.querySelector("#root")
        );
		/*
			Fragment Type을 통해서 태그가 없이,Child 부분이 나온다.
			필요한 이유는, 최상위 태그에서 태그에 구애 받지 않고, 여러 개를 작성하게 된다.
		*/ 
		
		// 4. 복잡한 리액트 엘리먼트 모음
		ReactDOM.render(
			React.createElement(
				"div",
				null,
				React.createElement(
					'div',
					null,
					React.createElement("h1", null, "주제"),
					React.createElement(
						"ul",
						null,
						ReactCreateElement("li", null, "React"),
						ReactCreateElement("li", null, "Vue")
					)
				)
			),
			document.querySelector('#root'),
		)
		

      // 4. props 를 통해 데이터를 주입
	    const Component = props => {
		    return React.createElement(
	        'p',
	        null,
	        `message 는 "${props.message}" 입니다.`,
		    );
	    };

	    ReactDOM.render(
	        React.createElement(
	            Component,
	            { message: '이것은 메세지 입니다.' },
	            null,
	        ),
	        document.querySelector('#root'),
        );

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

JSX

JSX

  • JSX 문법으로 작성된 코드는 순수한 JavaScript로 컴파일 하여 사용한다.
    • babel에서 컴파일을 해준다.

<!-- ex5.html : React.createElement 로 컴포넌트를 만들기 -->
<!DOCTYPE html>
<html lang="en">
  <head>...</head>
  <body>
    <div id="root"></div>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 
    <script type="text/babel">
	    // 4. 복잡한 리액트 엘리먼트 모음
	    ReactDOM.render(
		    <div>
			    <div>
				    <h1>주제</h1>
				    <ul>
					    <li>React</li>
					    <li>Vue</li>
					</ul>
				</div>
			</div>,
			document.querySelector("#root")
	    );
    </script>
  </body>
</html>
JSX를 사용하는 이유

  • 가독성이 좋다.
  • babel 과 같은 컴파일 과정에서 문법적 오류를 인지하기 쉽다.

JSX 문법

Props와 State

Props?

  • 컴포넌트 외부에서 컴포넌트에게 주는 데이터 입니다.

State?

  • 컴포넌트 내부에서 변경할 수 있는 데이터 입니다.

Screenshot 2023-06-11 at 6.36.08 PM.png

Render 함수

Function Component

<!-- ex8-1.html : 함수로 리액트 컴포넌트 만들기 -->
<!DOCTYPE html>
<html lang="en">
  <head>...</head>
  <body>
    <div id="root"></div>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
	    function Component(props) {
		    return (
		        <div>
			        <h1>{props.message} 이것은 함수로 만든 컴포넌트 입니다.</h1>
		        </div>
		    );
	    }
	
	    ReactDOM.render(
		    <Component message="안녕하세요!!!" />,
	        document.querySelector('#root'),
	    );
    </script>
  </body>
</html>

-> <Component p="데이터">props를 설정하며, props.p사용합니다.

Class Component

<!-- ex8-2.html : 클래스로 리액트 컴포넌트 만들기 -->
<!DOCTYPE html>
<html lang="en">
  <head>...</head>
  <body>
    <div id="root"></div>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
      class Component extends React.Component {
        render() {
          return (
            <div>
              <h1>
                {this.props.message} 이것은 클래스를 상속하여 만든 컴포넌트
                입니다.
              </h1>
            </div>
          );
        }
      }

      ReactDOM.render(
        <Component message="안녕하세요!!!" />,
        document.querySelector('#root'),
      );
    </script>
  </body>
</html>

Default Props

<!-- ex9.html : defaultProps 설정 -->
<!DOCTYPE html>
<html lang="en">
  <head>...</head>
  <body>
    <div id="root"></div>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
	    class Component extends React.Component {
		    static defaultProps = {
		        message: '안녕하세요!!!',
	        };
	        render() {
		        return (
			        <div>
			            {this.props.message} 이것은 클래스를 상속하여 만든 컴포넌트 입니다.
		            </div>
		        );
		    }
	    }
	    
		// state에 위치한 변수를 변경할 때는, 단순한 계산이 아닌 setState()를 이용해서 변경해야 한다.
		componentDidMount(){
		    setTimeout(()=>{
			    this.setState({
				    count: this.state.count+1,
			    })
		    },1000)
	    }
	
      //   Component.defaultProps = {
      //     message: '안녕하세요!!!',
      //   };

      ReactDOM.render(<Component />, document.querySelector('#root'));
    </script>
  </body>
</html>

State 사용법

// state 생성 방법 1
class Component extends React.Component {
  state = {
    s: '스테이트'
  };
  render() {
    return (
      <div>{this.state.s}</div>
    );
  }
}

// state 생성 방법 2
class Component extends React.Component {
  constructor(props) {
    super(props);
    this.state = {s: '스테이트'};
  }
  render() {
    return (
      <div>{this.state.s}</div>
    );
  }
}

사용 방법

state 값 변경 방법

class Component extends React.Component {
  state = {
    s: '스테이트'
  };
  render() {
    return (
      <div onClick={() => {
        this.setState({s: '새 스테이트'});
      }}>{this.state.s}</div>
    );
  }
}

Event Handling

Event Handling?

  • HTML DOM에 클릭하면 이벤트가 발생하고, 발생하면 그에 맞는 변경이 일어나도록 해야한다.
  • JSX에 이벤트를 설정할 수 있다.

Class Comp extends. React.Component{
	render(){
		return{
			<div>
				<button onClick={()=>{
					console.log('clicked');
				}}>클릭</button>
			</div>
		};
	}
}

규칙

예시 1

class Component extends React.Component{
	state = {
		count:0,
	};
	render(){
		return(
			<div>
				<p>{this.state.count}</p>
				<button
					onMouseEnter(()=>{
						console.log("clicked");
						this.setState((state)=>{
							...state,
							count: state.count + 1,
						})
					})
				>클릭</button>
			</div>
		)
	}
}

예시 2

class Component extends React.Component{
	state = {
		count:0,
	};
	// 첫번째
	constructor(props){
		super(props);
		this.click = this.click.bind(this);
		//위의 코드는 class 자체에 this를 props에 바인드 시켜서 강제로 맵핑 시킨다.
	}
	render(){
		return(
			<div>
				<p>{this.state.count}</p>
				<button
					onMouseEnter={this.click}
				>클릭</button>
			</div>
		)
	}
	//위의 코드를 수정 없이 그냥 사용하면 에러가 나기 때문에 위의 코드를 추가해야한다.
	// 혹은 위의 constructor를 지우고 clock = () => {} 방식으로 바꾼다면 해결된다.
	click(){
		console.log("clicked");
		this.setState((state)=>{
			...state,
			count: state.count + 1,
		})
	}
}

#React #FrontEnd