개발/React

React 기본 - Component, Props, Event, State

멍멍이코더 2023. 5. 3. 17:10

Component

리액트는 사용자 정의 태그를 만드는 기술이다. 우리는 이러한 사용자 정의 태그를 'Component' 즉, 컴포넌트라고 부른다.

function App() {
  return (
    <div className="App">
    
      // 헤더 영역
      <header>
      	<h4><a href='/'>HEADER</a></h4>
      </header>
      
      // 내비게이션 영역
      <nav>
      	<ul>
        	<li><a href='/read/1'>html</a></li>
        	<li><a href='/read/2'>css</a></li>
        	<li><a href='/read/3'>js</a></li>
        </ul>
      </nav>
      
      // 아티클 영역
      <article>
      	<h5>Welcome</h5>
        Hello, WEB
      </article>
      
    </div>
  );
}

export default App;

 

이런 기본 HTML 코드가 있다. 하지만 코드가 길어지게 되면 웹 페이지가 어떻게 생겼는지 파악하기가 쉽지 않을 것이다. 이렇게 어지러진 코드는 아래와 같이 Header, Nav, Article 컴포넌트를 이용해서 분리시킬수 있다.

💡 컴포넌트는 반드시 대문자로 시작해야 한다.

 

function Header(props) {
  console.log(props)
  return (
      <header>
      	<h4><a href='/'>HEADER</a></h4>
      </header>
  )
}

function Nav(props) {
  return (
    <nav>
      	<ul>
        	<li><a href='/read/1'>html</a></li>
        	<li><a href='/read/2'>css</a></li>
        	<li><a href='/read/3'>js</a></li>
        </ul>
    </nav>
  )
}

function Article({title, body}) {
  return (
      <article>
      	<h5>Welcome</h5>
        Hello, WEB
      </article>
  )
}

function App() {
  return (
    <div className="App">
      <Header />
      <Nav />
      <Article />
    </div>
  );
}

export default App;

 

Props

<img src='image.jpg' width='100' height='100' /> 와 같이 기본 HTML 엘리멘트에는 속성을 가진다. React에서도 이러한 속성을 가질 수 있는데, 이를 Prop이라고 부른다.  Props 는 Properties 의 줄임말이다. 우리가 어떠한 값을 컴포넌트에게 전달해줘야 할 때, Props 를 사용한다.

function Header(props) {
  console.log(props)
  return (
    <div>
      <header>
        <h3><a href='/'>{props.title}</a></h3>
      </header>
    </div>
  )
}

function Nav(props) {
  const lis = [];
  for (let i = 0; i < props.topics.length; i++) {
    let t = props.topics[i];
    lis.push(<li key={t.id}><a href={`/read/${t.id}`}>{t.title}</a></li>)
  }
  return (
    <nav>
      <ul>
        {lis}
      </ul>
    </nav>
  )
}


function App() {
  const topics = [
    {id:1, title: 'html', body: 'html is...'},
    {id:2, title: 'css', body: 'css is...'},
    {id:3, title: 'js', body: 'js is...'},
  ]
  return (
    <div className="App">
      <Header title="REACT" />
      <Nav topics={topics} />
    </div>
  );
}

export default App;

<li> 태그는 key라는 props를 가지고 있어야 하고, key라는 props의 값은 반복문 안에서 고유해야 한다.

 

 

💡 여러개의 props, 비구조화 할당

함수의 파라미터에서 비구조화 할당 (혹은 구조 분해) 문법을 사용하면 조금 더 코드를 간결하게 작성 할 수 있다.

function Article({title, body}) {
  return (
    <article>
      <h6>{title}</h6>
      {body}
    </article>
  )
}

function App() {
  return (
    <div className="App">
      <Article title="Welcome" body="Hello, Web" />
    </div>
  );
}

export default App;

 

💡 props.children

태그와 태그 사이의 모든 내용을 표시하기 위해 사용되는 특수한 props

✍️ props: 어떤 컴포넌트를 import해와서 사용하는 부모(상위) 컴포넌트에서 정하는 값. 부모 컴포넌트에서 설정해서 자식 컴포넌트로 전달하여, 자식 컴포넌트에서 쓰인다.
✍️ children: A 컴포넌트 사이에 B 컴포넌트가 있을 때, A 컴포넌트에서 B 컴포넌트 내용을 보여주려고 사용하는 props.

function Hello({children}) {
  return (
    <div>{children}</div>
  )
}


function App() {
  return (

    <div className="App">
      <Hello>
        <h3>Children</h3>
        <h3>Children</h3>
        <h3>Children</h3>
      </Hello>
    </div>
  );
}

export default App;

 

Event

function Header(props) {
  console.log(props)
  return (
    <div>
      <header>
        <h3><a href='/' onClick={(event) => {
          event.preventDefault();
          props.onChangeMode();
        }}>{props.title}</a></h3>
      </header>
    </div>
  )
}

function Nav(props) {
  const lis = [];
  for (let i = 0; i < props.topics.length; i++) {
    let t = props.topics[i];
    lis.push(<li key={t.id}><a id={t.id} href={`/read/${t.id}`} onClick={event => {
      event.preventDefault();
      props.onChangeMode(event.target.id);
    }}>{t.title}</a></li>)
  }
  return (
    <nav>
      <ul>
        {lis}
      </ul>
    </nav>
  )
}

function Article({title, body}) {
  return (
    <article>
      <h6>{title}</h6>
      {body}
    </article>
  )
}

function App() {
  const topics = [
    {id:1, title: 'html', body: 'html is...'},
    {id:2, title: 'css', body: 'css is...'},
    {id:3, title: 'js', body: 'js is...'},
  ]
  return (
  
    <div className="App">
      <Header title="REACT" onChangeMode={() => alert('Header')} />
      <Nav topics={topics} onChangeMode={(id) => alert(id)} />
      <Article title="Welcome" body="Hello, Web" />
    </div>
  );
}

export default App;

 

💡 HTML과의 차이점

1) React 이벤트 이름은 소문자 대신 camelCase를 사용
2) JSX에 문자열 대신 함수를 전달

// 기존 DOM element 에서 사용하는 방법
<button onclick="activateLasers()">
  Activate Lasers
</button>

// React에서 사용하는 방법
<button onClick={activateLasers}>
  Activate Lasers
</button>

위 예제를 살펴보면, onClick 와 같이 camelCase로 이벤트 이름을 설정하고, event handler의 연결은 JSX 표기인 { }을 사용하고 있다.

 

💡 주의할 점

DOM 요소에만 이벤트 설정이 가능하다. div, button, input, form, span 등의 DOM 요소에는 이벤트 설정이 가능하지만, 리액트의 컴포넌트에는 불가능하다. 예를 들면 위와 같이 button이라는 DOM 요소에 이벤트를 설정했는데, 아래처럼 <Component>라는 리액트 컴포넌트에는 onClick을 달아서 우리가 의도한대로 이벤트가 실행되지 않고, 그냥 color, name과 같은 props를 전달해주는 것에 불과하다.

function App() {
  const sayHi = function () {
    alert('hello');
  }
  return (
    <>
      <Component onClick={sayHi} name="홍길동" nickname="홍홍" />
    </>
  );
}

 

State

✍️ prop은 컴포넌트를 사용하는 외부자를 위한 데이터

✍️ state는 컴포너트를 만드는 내부자를 위한 데이터

 

state를 사용하려면 먼저 import를 하고, useState라는 훅을 사용해야 한다. 혹은 리액트에서 제공하는 기본적인 함수이다.

useState는 배열을 리턴하는데, 0번째 원소는 상태의 값을 읽을때 쓰는 데이터이고, 1번째 데이터는 상태의 값을 변경할 때 사용하는 함수이다. 다시 한번 정리하자면 useState의 인자는 그 state의 초깃값이다. 그리고 state의 값은 0번째 인덱스의 값으로 읽고, state의 값을 변경할때는 1번째 인덱스의 함수로 바꾼다,

function App() {
	const [mode, setMode] = useState('WELCOME');
}

 

사용 예시)

import { useState } from 'react';
import styles from './Button.module.css';

const App = () => {
    const [blueCount, setBlueCount] = useState(0);
    const [redCount, setRedCount] = useState(0);

    const handleBlueClick = () => {
        setBlueCount(blueCount + 1);
    };
    const handleRedClick = () => {
        setRedCount(redCount + 1);
    };

    return (
        <div>
            <div>
                <h3>파란색 버튼 클릭 횟수 : {blueCount}</h3>
                <button
                    id="blue"
                    className={styles.blueButton}
                    onClick={handleBlueClick}
                >
                    클릭해 보세요!
                </button>
            </div>
            <div>
                <h3>빨간색 버튼 클릭 횟수 : {redCount}</h3>
                <button
                    id="red"
                    className={styles.redButton}
                    onClick={handleRedClick}
                >
                    클릭해 보세요!
                </button>
            </div>
        </div>
    );
};

export default App;

 

 

 

해당 내용은 이고잉님의 '생활코딩! React 리액트 프로그래밍'에서 발췌한 내용입니다.

 

😎 관련게시글

React 기본 - UseEffect

 

 

반응형