반응형

📝React 이벤트 버블링

function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick();
    }}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('You clicked on the toolbar!');
    }}>
      <Button onClick={() => alert('Playing!')}>
        Play Movie
      </Button>
      <Button onClick={() => alert('Uploading!')}>
        Upload Image
      </Button>
    </div>
  );
}

부여된 JSX 태그 내에서만 실행되는 onScroll을 제외한 React 내의 모든 이벤트는 전파됩니다

이걸 막기 위해서는 e.stopPropagation()으로 버블링을 안 시킬 수 있습니다

 

애초에 이렇게 만드는게 이상한 듯 싶지만 Button 외를 클릭시에 어떤 동작을 하게 할 때 필요합니다

 

예제 코드

https://codesandbox.io/p/sandbox/react-dev-qqwck7?file=%2Fsrc%2FApp.js&utm_medium=sandpack

 

https://codesandbox.io/p/sandbox/react-dev-qqwck7?file=%2Fsrc%2FApp.js&utm_medium=sandpack

 

codesandbox.io

 

 

이벤트 버블링 참고내용

https://mondaymonday2.tistory.com/765

 

[JavaScript] 자바스크립트 이벤트 동작 과정 (이벤트 버블링, 이벤트 캡처, 이벤트 위임)

자바스크립트에서 이벤트가 동작되는 과정에는 두가지 방식이 있습니다. 기본적으로 이벤트 버블링으로 동작합니다. 📝이벤트 버블링 이벤트 버블링이란 하위 태그에서 이벤트가 발생할시 위

mondaymonday2.tistory.com

 

 

📝Props Drilling

보통의 경우 부모 컴포넌트에서 자식 컴포넌트로 props를 통해 정보를 전달하는데 중간에 많은 컴포넌트를 거쳐야하거나 하는경우 A의 값을 하위 B로 전달 B의 값을 하위 C로 전달... 계속적인 컴포넌트에 Props전달하는 경우를 의미합니다

 

 

📝Context를 이용해 Props Drilling 해결하기

 

 

Context를 사용하면 props를 전달하지 않아도 부모 컴포넌트에서 자식 컴포넌트에 한번에 보낼 수 있게 됩니다 간단하게 이야기하면 공통영역이 있어서 거기서 가져온다고 생각하면 됩니다

 

아래에서는 context API를 이용해 theme 즉 다크모드, 라이트모드 변경하는 예제하는 걸 보여드리겠습니다

 

다크모드인지 라이트모드인지에 대해서는 공통으로 최상단에서 관리해야하고 위에서 아래로 모든 컴포넌트에 계속 전달하기 어렵기 때문에 context API를 이용하는게 좋습니다

 

ThemeContext.js

import React, { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light'); // 초기 테마는 'light'

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

createContext로 context를 사용하기 위해 만듭니다

 

ThemeToggleButton

import React from 'react';
import { ThemeProvider, useTheme } from './ThemeContext';

const ThemeToggleButton = () => {
  const { theme, toggleTheme } = useContext(ThemeContext);

  const themeStyles = {
    backgroundColor: theme === 'light' ? '#FFF' : '#333',
    color: theme === 'light' ? '#333' : '#FFF',
  };

  return (
    <button style={themeStyles} onClick={toggleTheme}>
      Switch to {theme === 'light' ? 'Dark' : 'Light'} Mode
    </button>
  );
};

useContext로 Context에 선언된 state와 정보들을 가져오고 Toggle 버튼으로 theme값을 변경시키게 수정합니다

 

App.js

const App = () => {
  return (
    <ThemeProvider>
      <div>
        <h1>Hello, React Context API!</h1>
        <ThemeToggleButton />
      </div>
    </ThemeProvider>
  );
};

export default App;

전체 앱에 <ThemeProvider>로 감싸서 전체가 인식할 수 있게 합니다

 

 

context 사용 예시

  • context provider를 앱 최상단에 두고 시각적으로 조정이 필요한 컴포넌트에서 context를 사용할 수 있습니다.
  • 로그인한 사용자를 알아야 하는 컴포넌트가 많을 수 있습니다. Context에 놓으면 트리 어디에서나 편하게 알아낼 수 있습니다.
  • 애플리케이션이 커지면 결국 앱 상단에 수많은 state가 생기게 됩니다. 아래 멀리 떨어진 많은 컴포넌트가 그 값을 변경하고싶어할 수 있습니다.

 

context 문제점

  • 성능 이슈
    • Context API는 컴포넌트 트리의 모든 수준에서 데이터를 전달할 수 있지만, 종종 성능 문제를 일으킬 수 있습니다. Context를 사용하면 Context의 데이터가 변경될 때마다 해당 Context를 사용하는 모든 컴포넌트가 리렌더링됩니다. 이는 특히 대규모 애플리케이션에서 성능 저하를 유발할 수 있습니다.
  • 스케일링 문제
    • 작은 규모의 프로젝트에서는 효과적이지만, 애플리케이션이 커지면서 상태 관리가 복잡해질 때 Context API만으로는 관리가 어려워질 수 있습니다. 복잡한 상태 로직을 관리하고, 다양한 상태 변화를 효율적으로 처리하기 어려울 수 있습니다.
  • 구조적 한계
    • Context API는 전역 상태 관리보다는 주로 테마, 사용자 설정과 같이 고정적이고 간단한 데이터를 공유하는 데에 적합합니다. 복잡한 상태 변화와 비즈니스 로직을 포함하는 더 동적인 상태 관리에는 한계가 있습니다.

 

 

 

이러한 문제점을 해결하기 위해 다른 전역상태를 관리하는 툴을 많이 쓰는데 recoil,redux toolkit 등... 개인적으로 가장 많이 사용하는 redux toolkit을 사용하는게 좋습니다

 

반응형