HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👻
개발 기록
/
📑
강의 정리
/
📑
React 소개 ~ useRef
📑

React 소개 ~ useRef

Created
Oct 5, 2021 08:42 AM
Type
React
Mento
이선협님
Created By

React 소개

  • 페이스북에서 2013년 5월에 오픈 소스로 공개됨.
  • 반응형 프로그래밍.
  • 컴포넌트(재사용이 가능한 독립적인 객체)의 조합으로 View를 구성함.
  • Virtual Dom으로 필요한 부분만 한 번에 렌더링 하기 때문에 성능 최적화에 강함 → 편리함.
💡
처음엔 컴포넌트만 생각해보기! 재사용성과 확장성을 처음부터 생각하는 것은 어려움. 눈에 보이는 UL를 컴포넌트로 구현하는 것에 집중하기.

create-react-app, JSX

  • create-react-app : 리액트를 만들기 위한 가장 빠른 방법. npm init react-app my-app
  • src/App.js는 가장 기본이 되는 js 파일임. App 함수 내 가상 돔을 JSX라 부름.
    • class 대신 className을 사용.
    • npm start를 통해 실행할 수 있음(루트에 package.json의 scripts 영역에서 확인 가능).
    • {}를 사용하여 데이터를 다룸.

컴포넌트

  • 리액트 컴포넌트는 html, 로직, 스타일 정보를 담음.
  • 상태와 이벤트를 가짐.
  • 트리구조로 이루어져 서로 데이터와 메시지를 주고 받을 수 있음. 이때 데이터는 위에서 아래로 흐르기 때문에 단방향임.
import logo from "./logo.svg"; import propTypes from "prop-types"; function Logo({ size = 200 }) { return ( <img src={logo} className="App-logo" alt="logo" style={{ width: size, height: size }} /> ); } Logo.propTypes = { //size:propTypes.node.isRequired를 통해 props 입력을 강제할 수 있음. size: propTypes.number, }; export default Logo;
src/components/Logo/index.js
import "./App.css"; import Logo from "./components/Logo"; function App() { return ( <div className="App"> <header className="App-header"> <Logo size={100} /> <Logo /> </header> </div> ); } export default App;
src/App.js

어떻게 재사용 가능한 컴포넌트를 만들까?

  • UI를 추상적으로 바라보고 공통점 찾기.
  • 다른 동료가 어떤 컴포넌트인지 모를 정도로 쪼개면 안됨.
  • 점차적으로 규칙 정하기. ex) 도메인으로 분류, 역할로 분류, 크기로 분류
    • 정하는 것은 팀, 모두의 의견 존중하기.

상태와 이벤트 바인딩

Counter 만들기

import { useState } from "react"; import PropTypes from "prop-types"; function Counter({ onIncrease, onDecrease }) { const [count, setCount] = useState(0); const increaseCounter = () => { setCount(count + 1); if (onIncrease) onIncrease(count + 1); }; const decreaseCounter = () => { setCount(count - 1); if (onDecrease) onDecrease(count - 1); }; return ( <div> <span>{count}</span> <button onClick={increaseCounter}>+</button> <button onClick={decreaseCounter}>-</button> </div> ); } Counter.propTypes = { onIncrease: PropTypes.func, onDecrease: PropTypes.func, }; export default Counter;
src/components/Counter/index.js
import { useState } from "react"; import Counter from "./components/Counter"; function App() { const [totalCount, setTotalCount] = useState(0); return ( <div> totalCount : {totalCount} <Counter onIncrease={(count) => setTotalCount(totalCount + 1)} onDecrease={(count) => setTotalCount(totalCount - 1)} /> <Counter onIncrease={(count) => setTotalCount(totalCount + 1)} onDecrease={(count) => setTotalCount(totalCount - 1)} /> <Counter onIncrease={(count) => setTotalCount(totalCount + 1)} onDecrease={(count) => setTotalCount(totalCount - 1)} /> </div> ); } export default App;
src/App.js
  • useState를 통해 지역 상태를 관리할 수 있음.
  • 실행될 함수를 선언해 onClick이란 이벤트 바인딩을 통해 함수를 실행시킴.
  • 부모 컴포넌트에서 props를 통해 메시지를 받을 수 있도록 함수를 전달할 수 있음.

useEffect

  • 무언가 변화가 있을 때 감지하여 반응하는 Hook
// count의 변화를 감지. useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // 컴포넌트가 처음 로드될 때 실행됨. useEffect(() => { const handleScroll = () => { console.log(window.scrollY); } document.addEventListener("scroll", handleScroll()); //전역적인 이벤트 사용할 때 쓸 수 있음. return () => document.removeEventListener("scroll", handleScroll); //return으로 변환한 함수는 컴포넌트가 제거될 때 실행됨. }, []);

useRef

  • DOM에 직접 접근할 때 사용함.
  • 지역 변수로 사용할 때 사용함.
  • useState는 값이 변경될 때 다시 렌더링 되지만 useRef는 값이 변경돼도 다시 렌더링하지 않음.
function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` points to the mounted text input element inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> ); }