>웹 프론트엔드 >JS 튜토리얼 >예를 들어 React의 범위가 지정된 컨텍스트 설명

예를 들어 React의 범위가 지정된 컨텍스트 설명

Barbara Streisand
Barbara Streisand원래의
2024-12-26 09:11:10693검색

Explaining Scoped Context in React with example

React 컨텍스트는 전역 변수입니다

Javascript에서 변수의 범위는 함수 정의 내에서 지정됩니다.

예제를 통해 React의 범위가 지정된 컨텍스트 설명하기

React 컨텍스트는 전역 상태를 관리하는 메커니즘으로 종종 설명되며 React 구성 요소 트리에서 액세스할 수 있는 공유 변수 역할을 합니다. 이 설명은 정확하지만 컨텍스트의 기능을 지나치게 단순화합니다. 이 기사에서는 Context의 범위를 효과적으로 지정하여 필요한 경우에만 사용하고 불필요한 재렌더링을 방지하는 방법을 살펴보겠습니다.

리액트 컨텍스트란 무엇인가요?

React Context는 모든 수준에서 수동으로 props를 전달할 필요 없이 구성 요소 트리를 통해 데이터를 전달하는 방법을 제공합니다. React.createContext를 사용하여 생성되며 공급자와 소비자 쌍으로 구성됩니다. Provider 구성 요소는 값을 제공하며 Consumer 또는 useContext 후크로 래핑된 모든 구성 요소는 해당 값에 액세스할 수 있습니다.

기본적인 예는 다음과 같습니다.

import React, { createContext, useContext } from "react";

const ThemeContext = createContext("light");

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  return <ThemedButton />;
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button>{`Theme: ${theme}`}</button>;
}

export default App;

이 예에서 ThemedButton은 툴바를 통해 props를 명시적으로 전달하지 않고도 ThemeContext.Provider에서 제공하는 테마 값에 액세스할 수 있습니다.

왜 범위가 지정된 컨텍스트인가?

컨텍스트는 강력하지만 이를 무분별하게 사용하면 성능 문제가 발생할 수 있습니다. Context.Provider에서 제공하는 값이 변경되면 해당 컨텍스트를 사용하는 모든 구성 요소가 다시 렌더링됩니다. 복잡한 애플리케이션에서는 관련 없는 구성 요소가 불필요하게 다시 렌더링될 수 있습니다.

범위 지정 컨텍스트는 컨텍스트 사용을 실제로 필요한 구성 요소 트리 부분으로만 제한하는 방식을 의미합니다. 이 접근 방식은 성능을 유지하는 데 도움이 되며 구성 요소 구조를 깔끔하고 이해하기 쉽게 유지합니다.

복합 부품의 과제

Radix Primitives와 같은 라이브러리에서 제공하는 것과 같은 복합 구성 요소와 관련된 시나리오를 고려해보세요. 이러한 구성 요소는 내부적으로 Context를 사용하여 상태와 상호 작용을 관리하는 경우가 많습니다. 그러나 유사한 구성 요소가 함께 구성되면 문제가 발생하여 컨텍스트 충돌이 발생할 수 있습니다.

기수 프리미티브의 예

Radix Primitives는 접근 가능한 구성 요소를 구축하기 위한 구성 가능성이 높은 API를 제공합니다. 예는 다음과 같습니다.

<AlertDialog.Root>
  <Dialog.Root>
    <Dialog.Trigger />
    <Dialog.Content>
      <AlertDialog.Trigger /> {/* note the alert trigger in dialog content */}
    </Dialog.Content>
  </Dialog.Root>

  <AlertDialog.Content />
</AlertDialog.Root>

여기서 문제가 발생하는 이유는 AlertDialog가 AlertDialog 요구 사항을 충족하기 위한 추가 기능을 갖춘 Dialog의 구성이기 때문입니다. 즉, AlertDialog.Root도 Dialog.Root이므로 DialogContext와 AlertDialogContext를 모두 제공합니다.

이 설정에서는 AlertDialog.Trigger(Dialog.Trigger이기도 함)가 useContext(DialogContext)를 통해 잘못된 컨텍스트를 검색하여 AlertDialog.Root 대신 Dialog.Root의 컨텍스트로 끝날 수 있습니다. 결과적으로 AlertDialog.Trigger를 클릭하면 의도한 대로 작동하지 않고 Dialog.Content가 전환될 수 있습니다.

범위가 지정된 컨텍스트 솔루션

이러한 문제를 방지하기 위해 Radix Primitives는 범위가 지정된 컨텍스트를 사용합니다. 범위가 지정된 컨텍스트는 AlertDialog.Trigger가 AlertDialog 부분과만 상호 작용하고 유사하게 구성된 구성 요소에서 실수로 컨텍스트를 검색하지 않도록 보장합니다. 이는 내부적으로 새 컨텍스트를 생성하고 이를 __scopeDialog와 같은 사용자 정의 소품을 통해 Dialog 구성 요소에 전달함으로써 달성됩니다. 그런 다음 Dialog 구성 요소는 useContext 호출에서 이 범위 컨텍스트를 사용하여 격리를 보장합니다.

radix ui github 저장소의 소스 코드:

https://github.com/radix-ui/primitives/blob/dae8ef4920b45f736e2574abf23676efab103645/packages/react/dialog/src/Dialog.tsx#L69

다음은 Radix UI에서 범위가 지정된 컨텍스트가 작동하는 방식을 추상화한 것입니다.

  1. 범위 생성: createScope 유틸리티는 각 구성 요소 또는 복합 구성 요소에 대해 고유한 네임스페이스를 생성합니다. 이렇게 하면 각 컨텍스트 세트가 격리되고 다른 컨텍스트 세트와 충돌하지 않습니다.

    import React, { createContext, useContext } from "react";
    
    const ThemeContext = createContext("light");
    
    function App() {
      return (
        <ThemeContext.Provider value="dark">
          <Toolbar />
        </ThemeContext.Provider>
      );
    }
    
    function Toolbar() {
      return <ThemedButton />;
    }
    
    function ThemedButton() {
      const theme = useContext(ThemeContext);
      return <button>{`Theme: ${theme}`}</button>;
    }
    
    export default App;
    
  2. 범위가 지정된 공급자: 컨텍스트를 생성할 때 범위에 연결됩니다. 이는 공급자와 소비자를 동일한 네임스페이스에 바인딩합니다.

    <AlertDialog.Root>
      <Dialog.Root>
        <Dialog.Trigger />
        <Dialog.Content>
          <AlertDialog.Trigger /> {/* note the alert trigger in dialog content */}
        </Dialog.Content>
      </Dialog.Root>
    
      <AlertDialog.Content />
    </AlertDialog.Root>
    
  3. 소비자 격리: useDialogScope와 같은 범위 지정 후크는 소비자가 의도한 범위의 컨텍스트에만 액세스하도록 보장합니다.

    import { createScope } from '@radix-ui/react-context';
    
    const [createDialogContext, useDialogScope] = createScope('Dialog');
    

범위가 지정된 컨텍스트의 이점

  • 컨텍스트 충돌 방지: 컨텍스트 범위를 지정하면 AlertDialog.Trigger와 같은 구성 요소는 다른 컨텍스트 내에 중첩된 경우에도 항상 관련 컨텍스트(AlertDialogContext)를 찾을 수 있습니다.

  • 유연한 구성: 범위가 지정된 컨텍스트를 통해 구성 요소를 유연하고 안전하게 구성할 수 있으므로 상호 작용을 예측할 수 있습니다.

  • 재사용성: 개발자는 수정 없이 다양한 범위에서 일반 구성 요소(예: Dialog.Trigger)를 재사용할 수 있습니다.

예제에 적용되는 방법

귀하의 예에서는:

  • AlertDialog.Root는 해당 상태와 상호 작용을 캡슐화하는 범위가 지정된 AlertDialogContext를 생성합니다.

  • 중첩된 Dialog.Root와 AlertDialog.Trigger는 각각 해당 범위의 컨텍스트를 참조하므로 충돌 없이 공존합니다.

  • 이 디자인 패턴은 복잡한 구성 요소 계층 구조가 의도하지 않은 동작 없이 원활하게 작동하도록 보장하는 Radix UI의 핵심 기능입니다.

참고자료:

  1. https://dev.to/romaintrotard/use-context-selector-demystified-4f8e

  2. https://github.com/radix-ui/primitives

  3. https://react.dev/reference/react/createContext

위 내용은 예를 들어 React의 범위가 지정된 컨텍스트 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.