체인의정석

React 시작해보기 - 튜토리얼 사이트에서 기초 특징 빠르게 익히기 본문

개발/frontend

React 시작해보기 - 튜토리얼 사이트에서 기초 특징 빠르게 익히기

체인의정석 2023. 7. 15. 22:29
728x90
반응형

그간 프론트 엔드를 사용할때는 그냥 ejs, html, bootstrap 등만 사용했었는데

이젠 프론트 엔드 프레임워크를 하나쯤은 써보고 싶었다.

몇년 전부터 미루고 미루다가 드디어 react를 시작해보기로 마음 먹었다!

튜토리얼 사이트

무언가를 처음 배울 때 나는 무조건 공식 홈페이지의 튜토리얼 사이트 부터 본다.

https://react.dev/learn

 

Quick Start – React

The library for web and native user interfaces

react.dev

내가 원래 배우고 익히는 속도가 느리긴 하지만 그냥 나는 내 속도대로 천천히 공부해야지

컴포넌트

일단 컴포넌트라는 유익한 것을 바로 알려주는데 이렇게 함수를 만들어서 태그를 명시하고 난 후

function MyButton() {
  return (
    <button>I'm a button</button>
  );
}

이렇게 만들었던 함수를 사용하면 바로 그 태그가 원하는 위치에 들어간다고 한다.

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}

요걸 App.js 라는 파일에서 보면

function MyButton() {
  return (
    <button>
      I'm a button
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}

이렇게 된다고 한다.

export default 가 여기서 메인컴포넌트를 의미한다고 하는데 백엔드에서 모듈 export하는거랑 비슷한 느낌으로 이해하고 패스!

JSX에 대하여

우리가 본 위의 문법은 html이 아닌 jsx라고한다.

function AboutPage() {
  return (
    <>
      <h1>About</h1>
      <p>Hello there.<br />How do you do?</p>
    </>
  );
}

jsx는 html 보다 조금 더 strict 한데 그 이유는 바로 위와 같이 무조건 태그를 열어주었으면 닫아주어야 하기 때문이라고 한다.

다행히도 html을 jsx로 바꿔주는 사이트도 있다고 한다.

https://transform.tools/html-to-jsx

 

HTML to JSX

to TypeScript Declaration to TypeScript Declaration

transform.tools

어느정도 학습이 되면 내가 원하는 코드도 요걸로 한번에 바꿔봐야겠다 ㅋㅋㅋ


스타일 더하기

스타일 더할때는

<img className="avatar" />

이렇게 클래스 네임 더하듯이 더하면 된다고 한다.

/* In your CSS */
.avatar {
  border-radius: 50%;
}

 

데이터 보여주기

자바스크립트 문법을 더하고 싶을 땐 아래와 같이 { } 안에 코딩을 해주면 된다고 한다. 

return (
  <h1>
    {user.name}
  </h1>
);

그리고 이것도 정말 너무 편리해 보이는데

return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);

아닛... 이렇게 class name 지정해 준 후에 src를 쓰고 이미지 url을 넣어주게 되면?
바로 이미지를 넣어준 부분은 자바스크립트 코드로 작동한다고 한다.

const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}

조건문

조건문을 리액트에서 쓰는 법 또한 간단하다 그냥 if 를 그대로 써버리면 된다고 한다

let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);

이렇게 그냥 if else 문을 써서 화면을 다르게 보여줄 수 있다고 한다.

그리고 if 문 대신 자주쓰는 삼항연산자마냥

<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>

요것도 쓸 수 있다고 한다.

로그인이 되었는지 앞에 조건을 보고 true 면 admin panel을 리턴해주고 아니면 login form을 리턴해주는것이 그냥 삼항 연산자다

<div>
  {isLoggedIn && <AdminPanel />}
</div>

else가 필요 없으면 그냥 && 이걸로 끝내버려도 된다고 한다. 너무 간결하잖아~

랜더링 리스트

const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];

for 루프나 map 같은 애들은 백엔드에서 엄청 쓰는건데 당연히 프론트에서는 더 많이 쓰일 것 같다.

const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);

이런 식으로 하면 한번에 다 표시되는데 porduct.id 와 같은 키 값들이 데이터베이스의 id 같은 값 들이라고 한다.

const products = [
  { title: 'Cabbage', isFruit: false, id: 1 },
  { title: 'Garlic', isFruit: false, id: 2 },
  { title: 'Apple', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}

이런식으로 줄코딩 하드코딩을 쉽게 반복문으로 바꿔서 보여 줄 수 있다고 한다.

이벤트 반응하기

이벤트의 경우는 어떨까?

function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

이렇게만 하면 이벤트 핸들러를 안불러도 리액트가 알아서 불러준다고 한다.

스크린 업데이트 하기

뭔가 기억하고 꺼내고 싶었을때 나는 여태까지 사실 div를 만들고 hide 시켜놨었는데 ㅋㅋㅋ
이렇게 쓰면 된다고 한다.

import { useState } from 'react';

useState를 일단 가져오고

function MyButton() {
  const [count, setCount] = useState(0);
  // ...

이렇게 가져오기

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

useState(0)을 하면 count에 0이 세잍되고 그 뒤에 함수를 만들고 앞에 count + 1을 넣어주면 1씩 증가시켜 준다고 한다.

import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

이걸 보아하니 앞에는 변수이름 뒤에는 함수이름을 써두고 해당 변수를 사용하는 함수를 onClick 안에 해두면 휘발성 메모리 형태로 일단 올려두고 사용할 수 있는것 같다.

밑을 보니까 이건 hook이라 해서 그냥 내장 함수 같은 거였다 ㅋㅋㅋ 아무튼 비슷한 말이긴 하니 취소선만 남겨두고 설명은 유지시켜야지

Hook 사용하기

useState 와 같이 use가 앞에 붙은 애들을 hook이라고 한다고 한다.

https://react.dev/reference/react

 

Built-in React Hooks – React

The library for web and native user interfaces

react.dev

useState 말고 다양한 hook들이 있어서 유용하게 쓸 수 있을것 처럼 보인다.

useState에서 map, filter 이런애들은 useReducer로 바꿔서 넘길수도 있다고 하는데

나중에 자료형이 복잡해지면 더 간결하게 보여주는 느낌인 것 같다.

https://react.dev/learn/extracting-state-logic-into-a-reducer

 

Extracting State Logic into a Reducer – React

The library for web and native user interfaces

react.dev

컴포넌트 끼리 데이터 공유하기

원래 카운트는 이렇게 따로 올라간다고 치면

이렇게 동시에 올라가게 만들 수도 있는데

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  // ... we're moving code from here ...
}

myButton 함수의 내용물을 myApp 안으로 먼저 옮겨 준 후에

리턴 값에다가 그냥 태그를 넣어준다.

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

이렇게 출력물을 보내주는 것을 props 라고 부른다고 한다.

이제 count 상태변수랑 handleClick 이벤트 핸들러를 같이 리턴하게 된다.

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

그리고 최종적으로 MyButton에서 props를 읽어오게 만들면 된다.

import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

그 결과 나오는 위의 코드가 state up 된 형태여서 이제 이런 식으로 하게 되면 상태 변수를 동시에 관리 시킬 수 가 있다고한다.

 

728x90
반응형
Comments