React - 시작하기 (1. READ)

sarang_daddy·2023년 5월 2일
0

React

목록 보기
1/26
post-thumbnail

⛔️ 생활코딩 - 리액트 강의를 정리한 내용입니다.

컴포넌트

리엑트는 사용자 정의 태그를 만드는 기술이다.

  • 함수를 이용해서 사용자 정의 태그를 만든다.
  • 태그 이름은 반드시 대문자로 시작해야한다.
// Header라는 정의태그를 만든다.
function Header() {
  return (
    <header>
      <h1>
        <a href="/">WEB</a>
      </h1>
    </header>
  );
}

// Header라는 정의된 태그를 HTML에서 사용할 수 있다.
// 어디서는 Header라는 이름만으로 사용이 가능하다.
function App() {
  return (
    <div> 
      <Header></Header>
      <Header></Header>
    </div>
  );
}

// 정의된 태그의 내용만 수정해도 사용된 페이지 전체의 Header가 자동으로 수정된다.

이 사용자 정의 태그를 리엑트에서는 컴포넌트라고 부른다.

🤔 왜 컴포넌트를 사용하는가?

  • 컴포넌트 기술로 인해 태그를 독립된 하나의 부품으로 생성가능하고
  • 이 부품들을 이용하면 적은 복잡도로 소프트웨어를 만들 수 있다.
  • 또한, 내가 만든 혹은 다른 사람이 만든 컴포넌트의 공유 & 재사용이 가능하다.

Props(속성)

  • 컴포넌트에 Props(속성) 부여하기
function Header(props) {
  return (
    <header>
      <h1>
        <a href="/">{props.title}</a>
      </h1>
    </header>
  );
}

function App() {
  return (
    <div>
      <Header title="REACT"></Header>
    </div>
  );
}
  • Props를 사용하여 하드코딩을 없에고 동적으로 값 주기
// 하드코딩으로 만들어져있는 Nav 컴포넌트
function Nav() {
  return (
    <nav>
      <ol>
        <li><a href="/read/1">html</a></li>
        <li><a href="/read/2">css</a></li>
        <li><a href="/read/3">js</a></li>
      </ol>
    </nav>
  );
}

function App() {
  return (
    <div>
      <Nav></Nav>
    </div>
  );
}
// Props를 사용하여 동적으로 값을 주자.
function Nav(props) {
  const lis = props.topics.map((topic) => {
    // 동적으로 Nav태그의 li를 만들어 준다. 3️⃣
    return (
      // 동적으로 생성되는 Element에 key값 부여. 4️⃣
      // 동적으로 topic id, title 전달. 5️⃣
      <li key={topic.id}>
        <a href={`/read/${topic.id}`}>{topic.title}</a>
      </li>
    );
  });

  return (
    <nav>
      <ol>{lis}</ol>
    </nav>
  );
}

function App() {
  // Nav에 사용될 객체들이 존재한다고 했을 때, 1️⃣
  const topics = [
    { id: 1, title: "html", body: "html is..." },
    { id: 2, title: "css", body: "css is..." },
    { id: 3, title: "js", body: "js is..." },
  ];

  return (
	// Nav Props로 사용할 객체를 전달해준다. 2️⃣
    <div>
      <Nav title={topics}></Nav>
    </div>
  );
}

🚫 4️⃣ 처럼 동적으로 태그를 생성 할 때는 리엑트가 추적이 가능하다록 고유의 키값을 넣어주어야 한다.

이벤트

  • 컴포넌트에 이벤트 부여하기
function Header(props) {
  return (
    <header>
      <h1>
        <a
          href="/"
		  // onClick 이벤트 핸들러 추가. 2️⃣
          onClick={(event) => {
            event.preventDefault();
		    // props의 해당 이벤트 실행. 3️⃣
            props.onChangeMode();
          }}>
          {props.title}
        </a>
      </h1>
    </header>
  );
}

function App() {
  return (
    <div>
      <Header
        title="REACT"
		// Header 컴포넌트에 이벤트 Props 부여. 1️⃣
        onChangeMode={function () {
          alert("이벤트가 일어난다.");
        }}
      ></Header>
    </div>
  );
}
  • 1️⃣ 원하는 이벤트를 함수로 컴포넌트에 props 부여
  • 2️⃣ 컴포넌트 생성 함수에서 이벤트 핸들러 추가
  • 3️⃣ 이벤트 핸들러내에 props로 전달받은 이벤트 함수 실행

바닐라에서의 이벤트 등록과 잘 비교해보자.

const header = document.querySelector(".a")

// 1️⃣
const onChangeMode = () => {
    alert("이벤트가 일어난다")
}

// 2️⃣, 3️⃣
header.addEventListener("click", onChangeMode)

State(상태)

컴포넌트는 입력출력이 있다.
앞서 배운 Prop이 입력값이다. 컴포넌트는 Prop을 받고 return을 반환한다.
Prop말고 return을 반환하는 것이 하나더 존재하는데 그것이 State다.

새로운 return값을 만든다는 것은 UI를 바꾼다는 것이다.
즉, 컴포넌트는 Prop나 State로 부터 값을 받아서 UI를 변경한다.

  • Prop : 컴포넌트를 사용하는 외부자를 위한 데이터
  • State: 컴포넌트를 만드는 내부자를 위한 데이터

예제로 돌아가서 변수 mode가 바뀌면 Article의 내용이 변하도록 만들어보자.

function Article(props) {
  return (
    <article>
      <h2>{props.title}</h2>
      {props.body}
    </article>
  );
}

function App() {
  let mode = "Welcome";

  let content = null;

 // 변수 mode의 변경에 따라 content가 바뀌도록 구현
  if (mode === "Welcome") {
    content = <Article title="Welcom" body="Hello, Web"></Article>;
  } else if (mode === "Read") {
    content = <Article title="Read" body="Hello, Read"></Article>;
  }

 // Header 클릭시 mode는 'Welcome'
 // Nav 클릭시 mode는 'Read'
  return (
	  <div>
      <Header
        title="REACT"
        onChangeMode={function () {
          mode = "Welcome";
        }}
      ></Header>
      <Nav
        topics={topics}
        onChangeMode={() => {
          mode = "Read";
        }}
      ></Nav>
      {content}
    </div>
  );
}
  • Header와 Nav 컴포넌트의 이벤트 발생시 mode는 로직대로 “Welcome” ↔ “Read”로 변한다.
  • 하지만 content 즉, Article의 UI 변경을 일어나지 않는다.
  • App() 가 다시 실행되지 않았기 때문이다. → 리렌더링이 일어나지 않는다.
  • 여기서 필요한 기능이 State다.
// state 사용을 위해서는 useState라는 훅을 가져와야 한다.
// 훅은 react에서 기본적으로 제공해주는 함수다.
import {useState} from 'react'
// state를 사용할 변수에 useState를 적용한다.
// useState를 사용한 변수명에는 _를 달아준다.
let _mode = useState("Welcome");
// _mode를 살펴보자
console.log(_mode)

  • 0번째 원소는 상태의 값 가진다.
  • 1번째 원소는 상태의 값을 변경할 때 사용되는 함수를 가진다.
// _mode의 0번째, 1번째 원소들로 아래와 같이 사용할 수 있게 된다.
const mode = _mode[0] // 상태 값을 가진 변수
const setMode = _mode[1] // 상태 값을 변경하는 함수를 가진 함수

// 정리하여 mode라는 state를 사용한다면 아래와 같이 사용할 수 있다.
const [mode, setmode] = useState("Welcome")

위 예제를 state를 사용하여 다시 정리하면 아래와 같이 작성된다.


function App() {
  // useState를 사용하여 상태값과 상태 변경 함수를 가져옴
  const [mode, setMode] = useState("Welcome");

  let content = null;

 // 변수 mode의 상태 값에 따라 content가 바뀌도록 구현
  if (mode === "Welcome") {
    content = <Article title="Welcom" body="Hello, Web"></Article>;
  } else if (mode === "Read") {
    content = <Article title="Read" body="Hello, Read"></Article>;
  }

 // Header 클릭시 setMode('Welcome')
 // Nav 클릭시 setMode는('Read')
  return (
	<div>
      <Header
        title="REACT"
        onChangeMode={function () {
          setMode("Welcome");
        }}
      ></Header>
      <Nav
        topics={topics}
        onChangeMode={() => {
          setMode("Read");
        }}
      ></Nav>
      {content}
    </div>
  );
}
  • mode의 상태값을 setMode로 변경해주면 컨포넌트 App()이 재실행된다.
  • 즉, 상태변경 함수실행되면 해당 컴포넌트재실행 된다. → 렌더링이 일어난다.
  • 결국 상태값이 변경될 때 마다 UI가 변하는 결과를 확인할 수 있다.
// 클릭된 Nav의 ID값(상태)에 따라 title과 body가 변하게 할 수도 있다.

function App() {
  const [mode, setMode] = useState("Welcome");
  // 상태를 사용하기 위한 id, setId
  const [id, setId] = useState(null);

  const topics = [
    { id: 1, title: "html", body: "html is..." },
    { id: 2, title: "css", body: "css is..." },
    { id: 3, title: "js", body: "js is..." },
  ];

  let content = null;

  // mode가 "Read"일때, 클릭된 Nav의 ID(상태)를 변경해준다.
  if (mode === "Welcome") {
    content = <Article title="Welcom" body="Hello, Web"></Article>;
  } else if (mode === "Read") {
    let title, body = null;

	// 변경된 ID에 해당하는 title, body값을 가져온다.
    topics.forEach((topic) => {
      if (topic.id === id) {
        title = topic.title;
        body = topic.body;
      }
    });

    content = <Article title={title} body={body}></Article>;
  }

  return (
    <div>
      <Header
        title="REACT"
        onChangeMode={function () {
          setMode("Welcome");
        }}
      ></Header>
      <Nav
        topics={topics}
        onChangeMode={(_id) => {
		  // Nav를 클릭하면 mode가 변경되고
		  // 클릭된 Nav의 id로 setId 해준다.
		  // 그 후 App 컴포넌트는 재실행된다.
          setMode("Read");
          setId(_id);
        }}
      ></Nav>
      {content}
    </div>
  );
}

profile
한 발자국, 한 걸음 느리더라도 하루하루 발전하는 삶을 살자.

0개의 댓글