icon안동민 개발노트

React 기초 (컴포넌트, JSX, 상태 관리)


 React는 사용자 인터페이스를 구축하기 위한 선언적이고 효율적인 자바스크립트 라이브러리입니다.

 컴포넌트 기반 아키텍처, 가상 DOM, 단방향 데이터 흐름 등의 특징을 가지고 있어 다른 프레임워크와 차별화됩니다.

JSX

 JSX는 자바스크립트의 확장 문법으로, React 엘리먼트를 생성하는 데 사용됩니다.

const element = <h1>Hello, {name}</h1>;

 JSX vs 자바스크립트

  • JSX는 HTML과 유사한 문법을 사용하지만, 자바스크립트 내에서 직접 UI를 표현할 수 있습니다.
  • JSX는 컴파일 시 React.createElement() 호출로 변환됩니다.

React 컴포넌트

  1. 함수형 컴포넌트
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
  1. 클래스형 컴포넌트
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

 함수형 컴포넌트는 간결하고 Hook의 사용이 가능하며, 현재 React 개발의 주류입니다.

Props와 State

 Props

  • 부모 컴포넌트로부터 전달받는 읽기 전용 데이터
  • 컴포넌트의 재사용성을 높임
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
 
<Welcome name="Alice" />

 State

  • 컴포넌트 내부에서 관리되는 가변 데이터
  • useState Hook을 통해 관리 (함수형 컴포넌트)
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

생명주기와 Hooks

 클래스 컴포넌트의 생명주기 메서드 대신, 함수형 컴포넌트에서는 useEffect Hook을 사용합니다.

useEffect(() => {
  // 컴포넌트 마운트 시 실행
  console.log('Component mounted');
  return () => {
    // 컴포넌트 언마운트 시 실행
    console.log('Component will unmount');
  };
}, []); // 빈 배열은 컴포넌트 마운트/언마운트 시에만 실행

이벤트 처리

 React의 이벤트 처리는 camelCase를 사용하며, 함수를 이벤트 핸들러로 전달합니다.

function handleClick(e) {
  e.preventDefault();
  console.log('The link was clicked.');
}
 
return <a href="#" onClick={handleClick}>Click me</a>;

 주의사항

  • 이벤트 핸들러에 바인딩 필요 (화살표 함수 또는 bind 사용)
  • 합성 이벤트 사용 (브라우저 호환성 보장)

상태 관리

  1. useState Hook
const [state, setState] = useState(initialState);
  1. useReducer Hook (복잡한 상태 로직)
const [state, dispatch] = useReducer(reducer, initialState);
  1. Context API (전역 상태 관리)
const ThemeContext = React.createContext('light');
 
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}
 
function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
}

컴포넌트 간 통신

  1. Props Drilling : 부모에서 자식으로 props를 전달하는 방식
  2. Context API : 전역적으로 데이터를 공유할 수 있는 방법
  3. 상태 관리 라이브러리 : 복잡한 애플리케이션의 상태 관리에 사용

성능 최적화

 1. 메모이제이션

  • React.memo: 컴포넌트 메모이제이션
  • useMemo: 값 메모이제이션
  • useCallback: 함수 메모이제이션
const MemoizedComponent = React.memo(function MyComponent(props) {
  /* 렌더링 */
});
 
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
 
const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

 2. 코드 스플리팅

  • React.lazySuspense를 사용하여 필요한 시점에 코드를 로드
const OtherComponent = React.lazy(() => import('./OtherComponent'));
 
function MyComponent() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </React.Suspense>
  );
}

 React는 컴포넌트 기반의 UI 라이브러리로, 선언적 프로그래밍 패러다임을 따릅니다. 이는 개발자가 "어떻게" 구현할지보다 "무엇을" 구현할지에 집중할 수 있게 해줍니다. React의 가상 DOM과 효율적인 렌더링 알고리즘은 성능 최적화에 큰 도움을 줍니다.

 JSX는 React의 핵심 기능 중 하나로, 자바스크립트 내에서 HTML과 유사한 문법으로 UI를 표현할 수 있게 해줍니다. 이는 템플릿 언어가 아니라 자바스크립트의 확장이며, 컴파일 과정에서 일반 자바스크립트 함수 호출로 변환됩니다.

 React 컴포넌트는 함수형과 클래스형으로 나뉩니다. 최근에는 Hook의 도입으로 함수형 컴포넌트가 주류가 되었습니다. 함수형 컴포넌트는 더 간결하고 이해하기 쉬우며, 상태 관리와 생명주기 기능을 Hook을 통해 활용할 수 있습니다.

 Props와 State는 React에서 데이터를 다루는 두 가지 핵심 개념입니다. Props는 부모 컴포넌트로부터 전달받는 읽기 전용 데이터이며, State는 컴포넌트 내부에서 관리되는 가변 데이터입니다. 이 두 가지를 적절히 활용하여 컴포넌트의 동작을 제어하고 사용자 인터페이스를 구성합니다.

 React의 생명주기 메서드는 컴포넌트의 different stages를 이해하고 제어하는 데 중요합니다. 함수형 컴포넌트에서는 useEffect Hook을 통해 이러한 생명주기 기능을 구현할 수 있습니다.

 이벤트 처리는 React에서 중요한 부분입니다. React는 브라우저 호환성을 보장하기 위해 합성 이벤트 시스템을 사용합니다. 이벤트 핸들러 내에서 this의 바인딩에 주의해야 하며, 이는 화살표 함수를 사용하거나 명시적으로 bind를 호출하여 해결할 수 있습니다.

 상태 관리는 React 애플리케이션에서 중요한 부분입니다. 간단한 상태는 useState Hook으로, 복잡한 상태 로직은 useReducer Hook으로 관리할 수 있습니다. 전역 상태 관리가 필요한 경우 Context API나 Redux, MobX 같은 외부 라이브러리를 사용할 수 있습니다.

 컴포넌트 간 통신은 주로 props를 통해 이루어집니다. 그러나 깊은 컴포넌트 트리에서는 props drilling 문제가 발생할 수 있으며, 이는 Context API나 상태 관리 라이브러리를 통해 해결할 수 있습니다.

 React 애플리케이션의 성능 최적화는 중요한 과제입니다. 메모이제이션 기법을 통해 불필요한 재렌더링을 방지할 수 있으며, 코드 스플리팅을 통해 초기 로딩 시간을 줄일 수 있습니다. 또한, 가상화 기법을 사용하여 대량의 데이터를 효율적으로 렌더링할 수 있습니다.

 결론적으로, React는 강력하고 유연한 UI 라이브러리로, 적절히 사용하면 효율적이고 유지보수가 용이한 웹 애플리케이션을 구축할 수 있습니다. 그러나 이를 위해서는 React의 코어 컨셉과 Best Practices를 잘 이해하고 적용하는 것이 중요합니다.