window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster가 이미 존재합니다') } else { w.LeadBooster = { q: [], on: 함수 (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: 함수 (n) { this.q.push({ t: 't', n: n }) }, } } })() 조건부 렌더링 및 가드가 포함된 React의 컴포넌트 가시성 - The Codest
The Codest
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 산업 분야
    • 핀테크 및 뱅킹
    • E-commerce
    • 애드테크
    • 헬스 테크
    • 제조
    • 물류
    • 자동차
    • IOT
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
뒤로 화살표 뒤로 가기
2023-05-19
소프트웨어 개발

조건부 렌더링 및 가드를 사용한 React의 컴포넌트 가시성

바르틀로미예 쿠친스키

조건부 렌더링 및 가드 컴포넌트를 사용하여 React에서 컴포넌트 가시성을 간소화하고 개선하는 방법을 알아보세요.

오늘은 제어하는 방법에 대해 논의하고자 합니다. React의 구성 요소 가시성. 하지만 시작하기 전에 작은
면책 조항:

현재 제시된 솔루션은 '해커'(누구든)로부터 애플리케이션을 보호한다는 의미에서 그다지 안전하지 않습니다.
엔드포인트를 보호하고 애플리케이션 설계에 모범 사례를 사용해야 한다는 점을 기억하세요. 이 솔루션은
작업을 조금 더 쉽게 만들어 줍니다.

작업, 문제 해결 방법 또는 달성하고자 하는 목표

가장 일반적인 기능 중 하나는 특정 권한이 있는 사용자 그룹에 대해서만 컴포넌트를 표시하는 것입니다,
역할 또는 권한을 추가합니다. 일반적인 해결책은 일부 만약에 코드를 클릭하고 조건을 수동으로 확인하고 요소를 표시할지 여부를 선택합니다.

다음을 살펴보겠습니다. SimpleAppHeader 탐색 요소를 거의 포함하지 않는 컴포넌트입니다.

<!-- wp:paragraph -->
<p><code>타입스크립트 JSX<br>
export const SimpleAppHeader: FC = () =&gt; {<br>
    반환 (<br>
        <header><br>
            <nav><br>
                <ul><br>
                    {<br>
                        currentUser.role === "ADMIN" &amp;&amp;<br>
                        <li>관리자 전용 컴포넌트</li><br>
                    }<br>
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br>
                        <li>사용자 전용 구성 요소</li><br>
                    }<br>
                    {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;<br>
                        <li>관리자 및 사용자 전용 구성 요소</li><br>
                    }<br>
                    <li>일반 사용 요소</li><br>
                </ul><br>
            </nav><br>
        </header><br>
    )<br>
}<br>
</code></p>
<!-- /wp:paragraph -->

"나쁘지 않은" 것 같습니다. 아마도 검사를 함수로 캡슐화하여 복잡성을 줄일 수 있을 것입니다. currentUser 는 어떤 객체
그에는 역할 속성이지만, 제어 메커니즘의 대상으로 사용하고자 하는 모든 것이 될 수 있습니다.

이 코드에는 몇 가지 문제가 있습니다. 만약 프로젝트 가 성장하면 많은 곳에서 이 구조를 사용할 것입니다. 따라서 복사해야 합니다,
어떻게든, 조건. 이러한 코드는 향후 유지 관리 및 변경이 어렵습니다. 특히 다음 중 액세스 규칙이 변경되는 경우
시간 예: 변경이 필요한 경우 currentUser 를 다른 것으로 바꿔야 합니다. 테스트하기가 매우 어렵습니다. 많은 테스트를 작성해야 합니다.
상태가 괜찮은지 확인하기 위한 것입니다.

간소화

이제 이 코드를 조금 단순화할 차례입니다. 몇 가지 메서드를 추출하여 코드를 더 짧고 덜 복잡하게 만들 수 있습니다:

const isAdmin = (role: string): boolean => role === "ADMIN";
const isUser = (role: string): boolean => role === "USER";
const isAdminOrUser = (role: string): boolean => isAdmin(role) || isUser(role);

export const SimplifiedAppHeader: FC = () => {
반환 (

{

isAdmin(currentUser.role) &&
관리자 전용 컴포넌트

}
{
isUser(currentUser.role) &&

사용자 전용 컴포넌트

}
{
(isAdminOrUser(currentUser.role)) &&

관리자 및 사용자 전용 컴포넌트

}

일반 사용 요소

)
}
```

유망해 보입니다. 노이즈나 반복되는 줄이 줄어듭니다. 코드가 더 읽기 쉽고 유지 관리가 더 쉬워집니다. 하지만 다음을 살펴보세요.
함수 isAdminOrUser. 여기에는 두 가지 역할만 있습니다. 세 번째 역할을 도입하려면 다른 함수 집합을 만들어야 합니다.
역할을 결합한 버전입니다. 다른 버전으로 이동합니다.

필터링

기능을 소개합니다. hasRole 를 대체할 것입니다. isX 함수.

const hasRole = (role: string, requiredRole: string[]): boolean => {
let found: string | undefined = requiredRole.find(s => role === s);
반환 found !== undefined;
}

export const FilteringAppHeader: FC = () => {
반환 (

{

hasRole(currentUser.role, ["ADMIN"]) &&
관리자 전용 컴포넌트

}
{
hasRole(currentUser.role, ["USER"]) &&

사용자 전용 컴포넌트

}
{
hasRole(currentUser.role, ["ADMIN", "USER"]) &&

관리자 및 사용자 전용 컴포넌트

}

일반 사용 요소

)
}
```

이제 괜찮아 보입니다. 여전히 코드의 HTML 부분에 조건이 있지만 이제 테스트할 수 있습니다. hasRole 기능 및 신뢰
가 올바른 매개변수 집합과 함께 사용됩니다. 이제 역할을 추가하거나 변경하기가 더 쉬워졌습니다. 모든 역할이 포함된 배열을 사용합니다.
필요한 역할을 수행합니다.

그러나 이 솔루션은 currentUser 객체입니다. 객체가 어떤 식으로든 전역적이거나 접근하기 쉽다고 가정합니다.
애플리케이션의 모든 위치에서 사용할 수 있습니다. 그래서 우리는 이것을 캡슐화하려고 할 수 있습니다. 물론 hasRole 함수입니다:

 const hasRole = (requiredRole: string[]): boolean => {
     let found: string | undefined = requiredRole.find(s => currentUser.role === s);
     return found !== undefined;
 }

그러나 그것은 우리에게 거의 아무것도 제공하지 않습니다.

그리고 Guard 구성 요소

이제 전체 로직을 캡슐화하는 컴포넌트를 만들 차례입니다. 이름을 Guard 이렇게 사용하고 싶습니다.

export const GuardedAppHeader: FC = () => {
     반환 (
         
  • 관리자 전용 컴포넌트
  • 사용자 전용 구성 요소
  • 관리자 및 사용자 구성 요소
  • 일반 사용 요소
); }

컴포넌트에는 두 가지 속성이 필요합니다. 첫째 어린이 보호되는 콘텐츠에 대한 책임이 있습니다. 둘째 필수 역할 그
액세스 권한을 부여하는 역할 배열을 처리합니다.

이 구조의 표현이 필요합니다. 매우 간단합니다. 우리는 타입을 확장합니다. React.PropsWithChildren 그에는 어린이
속성을 추가합니다. 물론 해당 속성을 유형에 수동으로 추가하고 확장자를 생략할 수도 있습니다.

인터페이스 IGuardProps 확장 React.PropsWithChildren {
requiredRoles: 문자열[];
}

구성 요소 자체도 간단합니다. 우리는 재사용할 것입니다 hasRole 함수를 사용할 수 있습니다.

export const Guard = (props: IGuardProps) => {
const hasRole = (requiredRole: string[]): boolean => {
let found: string | undefined = requiredRole.find(s => currentUser.role === s);
return found !== undefined;
}

if (hasRole(props.requiredRoles)) {
    return (
        
            {props.children}
        
    );
} else {
    반환 ;
}
}
"`

여기서 멈추라고 말할 수도 있지만 너무 쉬울 것입니다. 이제 컴포넌트가 생겼고, 이를 극한까지 활용할 수 있습니다 😀.

`GuardService`

첫 번째 단계는 수표의 외부화입니다. currentUser 는 하드코딩된 값입니다. 이 값을 캡슐화하고 싶습니다.
를 일부 서비스에 추가하면 역할을 확인하는 방법을 '알게' 됩니다. 기술적으로 이는 우리가 hasRole 함수를 다른
클래스.

간단한 인터페이스를 만듭니다. IGuardService 속성이 하나만 있는 경우 - hasRole.

내보내기 인터페이스 IGuardService {
checkRole: (roles: string[]) => boolean;
}

이제 간단한 구현은 다음과 같습니다.

SimpleGuard 클래스는 IGuardService를 구현합니다 {
checkRole(roles: string[]): boolean {
let found: 문자열 | undefined = roles.find(e => e === currentUser.role);
return found !== undefined;
}
}

이를 사용하려면 다음을 변경해야 합니다. IGuardProperties 및 사용 사례.

내보내기 인터페이스 IGuardProps는 React.PropsWithChildren을 확장합니다.
requiredRoles: 문자열[];
guardService: IGuardService;
}

// ...

const AppHeader: FC = () => {
const guardService = 새로운 SimpleGuard();
반환 (

관리자 전용 컴포넌트
 

사용자 전용 컴포넌트

관리자 및 사용자 구성 요소
 
 

일반 사용 요소

 

);
}
```

이제 컴포넌트는 다음과 같습니다:

 export const Guard = (props: IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) { {
         반환 (
             
                 {props.children}
             
         );
     } else {
         반환 ;
     }
 }
 

훨씬 나아졌습니다. GuardService 역할을 확인하는 로직으로부터 우리를 분리합니다. 우리는 우리의
컴포넌트입니다. 일반적인 사용 사례는 테스트에서는 모의 구현을 사용하고 프로덕션 코드에서는 일부 "실제" 구현을 사용하는 것입니다.

금지된 요소

다음 개선 사항은 사용자 지정 처리입니다. 금지됨 요소를 렌더링합니다. 현재 솔루션은 빈 요소를 렌더링합니다. 먼저
변경 IGuardProps 해당 요소를 렌더링할 함수를 추가합니다.

내보내기 인터페이스 IGuardProps 확장 React.PropsWithChildren {
     requiredRoles: 문자열[];
     guardService: IGuardService;
     forbidden?: () => React.ReactNode;
 }

이 속성은 선택적 속성이며 이름은 물음표 문자로 끝납니다. 따라서 함수 또는 정의되지 않음. 다음을 수행해야 합니다.
에서 처리합니다. Guard 컴포넌트입니다.

export const Guard = (props: IGuardProps) => {{
if (props.guardService.checkRole(props.requiredRoles)) { {
반환 (

{props.children}

);
} else if (props.forbidden === undefined) {
반환 ;
} else {
반환 (
{props.forbidden()}

);
}
}

// ...

export const AppHeader: FC = () => {
const guardService = 새로운 SimpleGuard();
반환 (

관리자 전용 컴포넌트
 

사용자 전용 컴포넌트

금지됨 - 관리자만 볼 수 있습니다.
}>
 

중재자 구성 요소

 

관리자 및 사용자 구성 요소
 
 

일반 사용 요소

 

);
}
```

유형의 유연성

마지막 큰 변화를 맞이할 시간입니다. 현재 버전 컴포넌트는 다음과 같은 역할만 지원합니다. 문자열. 여러 가지 다른
확인하려는 속성 유형입니다. 숫자나 사용자 정의 유형은 특별한 것이 아닙니다. 제네릭 지원을 추가하겠습니다.

첫 번째 단계는 IGuardService 인터페이스가 필요합니다. 구현은 테스트된 값의 유형에 따라 달라집니다. 다음과 같습니다.
가 무엇이든 될 수 있으므로 인터페이스가 이를 처리해야 합니다.

 export interface IGuardService {
     checkRole: (roles: ROLE[]) => boolean;
 }

이제 다음과 같은 배열이 필요합니다. 역할 일반 유형. 간단한 구현이 약간 변경됩니다.

 SimpleGuard 클래스는 IGuardService를 구현합니다.
     checkRole(roles: string[]): boolean {
         let found: string | undefined = roles.find(e => e === currentUser.role);
         return found !== undefined;
     }
 }

유형 매개 변수를 추가해야 하지만 다음을 지원하는 구현을 준비할 수 있습니다. IRole 인터페이스.

인터페이스 IRole {
이름: 문자열;
}

//...
RoleGuardService 클래스는 IGuardService를 구현합니다 {
checkRole(roles: IRole[]): boolean {
let find: IRole | undefined = roles.find(e => e === userWithRole.role);
return found !== undefined;
}
}
```

두 번째 단계는 이 변경 사항을 다음과 같이 전파하는 것입니다. IGuardProps.

인터페이스 IGuardProps 확장 React.PropsWithChildren {
     requiredRoles: ROLE[];
     guardService: IGuardService;
     forbidden?: () => React.ReactNode;
 }

그리고 각각 Guard 컴포넌트입니다.

export const Guard = (props: IGuardProps) => {
     if (props.guardService.checkRole(props.requiredRoles)) { {
         반환 (
             
                 {props.children}
             
         );
     } else if (props.forbidden === undefined) {
         반환 ;
     } else {
         반환 (
                 {props.forbidden()}
             
         );
     }
 }

그리고 사용 사례

export const AppHeader: FC = () =&gt; {
     const guardService = 새로운 SimpleGuard();
     const roleService = new RoleGuardService();
     반환 (
         <header>
             <nav>
                 <ul>
                     <Guard<IRole&gt; requiredRoles={[{name: "ADMIN"}]} guardService={roleService}&gt;
                         <li>관리자 전용 구성 요소</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                         <li>사용자 전용 구성 요소</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                    forbidden={() =&gt; <div>금지됨 - 운영자만 볼 수 있습니다.</div>}>
                         <li>진행자 구성 요소</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <li>관리자 및 사용자 구성 요소</li>
                     </Guard>
                     <li>일반 사용 요소</li>
                 </ul>
             </nav>
         </header>
     );
 }

이 예제에서는 두 가지 구현을 모두 사용합니다. IGuardservice 를 예로 들었습니다. 실제 사용 사례에서는
아마 하나만 사용할 것입니다.

특수 구성 요소 및 중첩

그리고 Guard 를 중첩할 수 있습니다. 액세스 권한은 대부분의 외부 인스턴스 순서대로 해결된다는 점만 기억하세요.

export const NestAppHeader: FC = () =&gt; {
     const guardService = 새로운 SimpleGuard();
     반환 (
         <header>
             <nav>
                 <ul>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt;
                         <Guard<string&gt; requiredRoles={["ADMIN"]} guardService={guardService}&gt;
                             <li>관리자 전용 구성 요소</li>
                         </Guard>
                         <Guard<string&gt; requiredRoles={["USER"]} guardService={guardService}&gt;
                             <li>사용자 전용 구성 요소</li>
                         </Guard>
                         <li>관리자 및 사용자 구성 요소</li>
                         <Guard<string&gt; requiredRoles={["MODERATOR"]} guardService={guardService}
                                        forbidden={() =&gt; <div>금지됨 - 운영자만 볼 수 있습니다.</div>}>
                             <li>진행자 구성 요소</li>
                         </Guard>
                     </Guard>
                     <li>일반 사용 요소</li>
                 </ul>
             </nav>
         </header>
     );
 }

위의 예에서 진행자 구성 요소 는 사용자가 하나의 역할만 처리할 수 있기 때문에 표시되지 않을 수 있습니다. First Guard 제한
역할 ADMIN 그리고 USER따라서 사회자 는 첫 번째 확인을 통과하지 못합니다.

일부 속성을 숨기는 특수 컴포넌트를 만들 수 있습니다.

export const AdminGuard = (props: Omit) => {
return 
{props.children}

}

//...
export const SpecializedAppHeader: FC = () => {
const guardService = new SimpleGuard();
반환 (

관리자 전용 컴포넌트
 


사용자 전용 컴포넌트


금지됨 - 중재자만 볼 수 있음
}>

중재자 컴포넌트



관리자 및 사용자 컴포넌트

 

일반 사용 요소

);
}
```

이 경우 AdminGuard 미리 정의 ADMIN 역할을 정의해야 합니다. 결과적으로 다음과 같은 유형을 명시적으로 정의해야 합니다. 역할 유형
매개변수입니다.

요약

이 문서에서는 다음을 만들고 사용하는 방법을 설명합니다. Guard React의 구성 요소. 우리는 이해하기 어려운 복잡한 코드에서 시작합니다.
읽고 유지 관리합니다. 보다 개발자 친화적인 상태로 발전시키고 사용자 지정 기능 구성 요소를 도입합니다. 다음으로
추가 기능을 추가하는 컴포넌트 확장, 추출 서비스 리팩터링, 마지막으로 제네릭 유형을 추가합니다.

마지막으로 테스트 및 유지 관리가 쉬운 중첩 가능한 컴포넌트가 있습니다.

관련 문서

소프트웨어 개발

React의 장단점

React를 사용해야 하는 이유는 무엇인가요? JavaScript 라이브러리의 장점은 무엇일까요? 이 글을 자세히 살펴보고 React 사용의 실제 이점에 대해 알아보세요.

The Codest
세자리 고랄스키 Software Engineer

지식창고를 구독하고 IT 분야의 전문 지식을 최신 상태로 유지하세요.

    회사 소개

    The Codest - 폴란드에 기술 허브를 둔 국제 소프트웨어 개발 회사입니다.

    영국 - 본사

    • 사무실 303B, 182-184 하이 스트리트 노스 E6 2JA
      영국 런던

    폴란드 - 현지 기술 허브

    • 파브리츠나 오피스 파크, 알레야
      포코주 18, 31-564 크라쿠프
    • 뇌 대사관, 콘스트럭터스카
      11, 02-673 바르샤바, 폴란드

      The Codest

    • 홈
    • 회사 소개
    • 서비스
    • Case Studies
    • 방법 알아보기
    • 채용 정보
    • 사전

      서비스

    • IT 자문
    • 소프트웨어 개발
    • 백엔드 개발
    • 프론트엔드 개발
    • Staff Augmentation
    • 백엔드 개발자
    • 클라우드 엔지니어
    • 데이터 엔지니어
    • 기타
    • QA 엔지니어

      리소스

    • 외부 소프트웨어 개발 파트너와의 협력에 대한 사실과 오해
    • 미국에서 유럽으로: 미국 스타트업이 유럽으로 이전을 결정하는 이유
    • 테크 오프쇼어 개발 허브 비교: 테크 오프쇼어 유럽(폴란드), 아세안(필리핀), 유라시아(터키)
    • CTO와 CIO의 주요 과제는 무엇인가요?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • 웹사이트 이용 약관

    저작권 © 2025 by The Codest. 모든 권리 보유.

    ko_KRKorean
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese es_ESSpanish nl_NLDutch etEstonian elGreek ko_KRKorean