s00jin 님의 블로그

[오픈미션] 리액트 공부 1 본문

우아한테크코스

[오픈미션] 리액트 공부 1

s00jin 2025. 11. 24. 18:00

리액트 기초 강의를 정리한 내용입니다.


리액트는  페이지 전체를 한 번에 만드는 방식이 아니라

컴포넌트 단위로 조립해서 사용하는 방식

리액트 작업 환경 만들기

npx create-react-app my-app
// my-app 부분은 작업할 디렉토리

npx create-react-app .
// .은 현재 디렉토리를 의미

개발 시 서버 실행

npm start
// 리액트 실행

src/index.js 파일이 실행시 처음 실행되는 파일 (메인 파일 느낌?)

배포시 빌드

npm run build

 

사용하면 build 폴더 생김

npx serve -s build // -s 옵션은 build 폴더의 index.js로 시작하게 해주는 옵션

위 명령어 실행하면 index.js로 시작하는 서버 배포됨


컴포넌트 만들기

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div>
      <header>
        <h1><a href="/">WEB</a></h1>
      </header>
      <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>
      <article>
        <h2>WELCOME</h2>
        Hello, WEB!
      </article>
    </div>
  );
}

export default App;

만약 위 코드에서 header, nav, article이 각각 1억줄씩 있다고 생각하면 너무!~~ 어지러움

정리정돈을 해야함

정리정돈은 서로 연관된 것들을 모음 → 거기다 이름을 붙임

 

사용자 정의 태그 정의하기 = 컴포넌트 (컴퍼넌트)

  • 앞글자는 무조건 대문자
import logo from './logo.svg';
import './App.css';
function Header() {
  return <header>
        <h1><a href="/">React</a></h1>
      </header>
}
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 Article() {
  return <article>
        <h2>WELCOME</h2>
        Hello, WEB!
      </article>
}
function App() {
  return (
    <div>
      <Header></Header>   
      <Nav></Nav>
      <Article></Article>
    </div>
  );
}

export default App;

이렇게 Header() 만든게 컴퍼넌트

props (데이터 전달)

부모 -> 자식 컴포넌트로 값 전달할 수 있음

<Header title="React" />

컴포넌트에서는

function Header(props) {
  return <h1>{props.title}</h1>
}

 

더보기
import logo from './logo.svg';
import './App.css';
function Header(props) { // props 말고 다른 이름이 와도 됨. 하지만 다들 props라고 함
  console.log('props', props, props.title);
  return <header>
        <h1><a href="/">{props.title}</a></h1> // 리턴에 있는 html에서는 {} 중괄호로 감싸줘야 문자열이 아니라 표현식으로 취급
      </header>
}
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 Article(props) {
  return <article>
        <h2>{props.title}</h2>
        {props.body}
      </article>
}
function App() {
  return (
    <div>
      <Header title="React"></Header>   
      <Nav></Nav>
      <Article title="Welcome" body="Hello, Web!"></Article>
      <Article title="Hi" body="React!"></Article>
    </div>
  );
}

export default App;

li의 값이 하드코딩이라 별로임

import logo from './logo.svg';
import './App.css';
function Header(props) {
  console.log('props', props, props.title);
  return <header>
        <h1><a href="/">{props.title}</a></h1>
      </header>
}
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>
        <ol>
          {lis}
        </ol>
      </nav>
}
function Article(props) {
  return <article>
        <h2>{props.title}</h2>
        {props.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>
      <Header title="React"></Header>   
      <Nav topics={topics}></Nav>
      <Article title="Welcome" body="Hello, Web!"></Article>
      <Article title="Hi" body="React!"></Article>
    </div>
  );
}

export default App;


위에서 처럼 배열 lis를 만든 후 {lis} 해주면 리액트에서 자동으로 안에 요소들 해줌

배열 요소들을 하나씩 꺼내서 배치해줌

이벤트

onClick={(event) => {
  event.preventDefault();
  props.onChangeMode();
}}

 

  • event.preventDefault() : 기본 동작 막음
  • props.onChangeMode() : 부모에서 내려준 함수 실행

이벤트에서 특정 값을 전달하고 싶으면

props.onChangeMode(event.target.id)

event.target은 이벤트 발생한 DOM 요소

 

더보기
import logo from './logo.svg';
import './App.css';
function Header(props) {
  console.log('props', props, props.title);
  return <header>
        <h1><a href="/" onClick={function(event) {
          event.preventDefault();
          props.onChangeMode();
        }}>{props.title}</a></h1>
      </header>
}
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>
        <ol>
          {lis}
        </ol>
      </nav>
}
function Article(props) {
  return <article>
        <h2>{props.title}</h2>
        {props.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>
      <Header title="React" onChangeMode={function() {
        alert('Header');
      }}></Header>   
      <Nav topics={topics}></Nav>
      <Article title="Welcome" body="Hello, Web!"></Article>
      <Article title="Hi" body="React!"></Article>
    </div>
  );
}

export default App;

 

 화살표 함수로 변경해서 적용할 시

import logo from './logo.svg';
import './App.css';
function Header(props) {
  console.log('props', props, props.title);
  return <header>
        <h1><a href="/" onClick={(event) =>{
          event.preventDefault();
          props.onChangeMode();
        }}>{props.title}</a></h1>
      </header>
}
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>
        <ol>
          {lis}
        </ol>
      </nav>
}
function Article(props) {
  return <article>
        <h2>{props.title}</h2>
        {props.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>
      <Header title="React" onChangeMode={() => {
        alert('Header');
      }}></Header>   
      <Nav topics={topics}></Nav>
      <Article title="Welcome" body="Hello, Web!"></Article>
      <Article title="Hi" body="React!"></Article>
    </div>
  );
}

export default App;

 

 

State

 

const [mode, setMode] = useState('WELCOME');
const [id, setId] = useState(null);

 

  • mode가 바뀌면 자동으로 UI가 업데이트됨
  • React는 데이터가 바뀌면 화면을 다시 렌더링한다는 개념
  • 주의 ) 입력값을 태그 속성값으로 넣을 때 문자로 변환 됨. (숫자도)

Create

 

 

 

새 배열을 만들고 추가해야함!!

setTopics([...topics, newTopic]);

여기서 ...은 topics를 그대로 복붙하는 것

 

Update

 

  • useState로 기존 값을 기본값으로 채움
  • onSubmit에서 업데이트 실행
  • create + read 같은 느낌임. 하이브리드 처럼 사용

Delete

“실제로 삭제”가 아니라,
해당 id를 제외한 새로운 배열을 만들어 교체하는 방식

 

참고 강의 및 자료

https://www.youtube.com/playlist?list=PLuHgQVnccGMCOGstdDZvH41x0Vtvwyxu7

 

React 2022 개정판

 

www.youtube.com

빠르게 시작하기 – React

 

빠르게 시작하기 – React

The library for web and native user interfaces

ko.react.dev

 

 

'우아한테크코스' 카테고리의 다른 글

[오픈미션] 리액트 공부 3  (0) 2025.11.24
[오픈미션] 리액트 공부 2  (0) 2025.11.24
[오픈미션] Javascript 공부  (0) 2025.11.24
[회고] 1주차 프리코스 회고  (0) 2025.10.22
Git 커밋 메시지 정리본  (0) 2025.10.18