window.pipedriveLeadboosterConfig={です。 ベース:'leadbooster-chat.pipedrive.com'、 companyId:11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2、 } ;(function () { var w = window もし (w.LeadBooster) {なら console.warn('LeadBooster already exists') } else { w.LeadBooster = { {. q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: 関数 (n) { { this.q.push({ t: 'o', n: n, h: h }) this.q.push({ t: 't', n: n }) }, } } })() 条件付きレンダリングとガードによるReactでのコンポーネントの可視性 - The Codest
The Codest
  • 会社概要
  • サービス
    • ソフトウェア開発
      • フロントエンド開発
      • バックエンド開発
    • Staff Augmentation
      • フロントエンド開発者
      • バックエンド開発者
      • データエンジニア
      • クラウドエンジニア
      • QAエンジニア
      • その他
    • アドバイザリー
      • 監査&コンサルティング
  • 産業
    • フィンテック&バンキング
    • E-commerce
    • アドテック
    • ヘルステック
    • 製造業
    • 物流
    • 自動車
    • アイオーティー
  • 価値
    • CEO
    • CTO
    • デリバリー・マネージャー
  • チーム
  • Case Studies
  • ノウハウ
    • ブログ
    • ミートアップ
    • ウェビナー
    • リソース
採用情報 連絡先
  • 会社概要
  • サービス
    • ソフトウェア開発
      • フロントエンド開発
      • バックエンド開発
    • Staff Augmentation
      • フロントエンド開発者
      • バックエンド開発者
      • データエンジニア
      • クラウドエンジニア
      • QAエンジニア
      • その他
    • アドバイザリー
      • 監査&コンサルティング
  • 価値
    • CEO
    • CTO
    • デリバリー・マネージャー
  • チーム
  • Case Studies
  • ノウハウ
    • ブログ
    • ミートアップ
    • ウェビナー
    • リソース
採用情報 連絡先
戻る矢印 戻る
2023-05-19
ソフトウェア開発

Reactにおける条件付きレンダリングとガードによるコンポーネントの可視化

バルトロミエ・クジンスキー

条件付きレンダリングとガード・コンポーネントを使用して、Reactでコンポーネントの可視性を簡素化し、改善する方法を紹介します。

今日は、そのコントロール方法についてお話したいと思う。 Reactのコンポーネントの可視性.しかし、その前に小さなことがある。
免責事項

提示されたソリューションは、あなたのアプリケーションを「ハッカー」(誰であろうと)から守るという意味では、あまり安全ではありません。
エンドポイントを保護し、アプリケーションの設計に良い習慣を用いる必要があることを忘れないでください。この解決策は
あなたの仕事を少し楽にするだけです。

課題、問題解決、または達成したいこと

最も一般的な機能の1つは、特定の権限を持つユーザーのみにコンポーネントを表示することです、
ロールや権限を追加することです。一般的な解決策は もしへの コード手動で条件をチェックし、エレメントを表示するかしないかを決める。

を見てみよう。 シンプルAppヘッダー コンポーネントは、ナビゲーション要素をほとんど含まない。

<!-- wp:paragraph -->
<p><code>タイプスクリプト jsx<br>
export const SimpleAppHeader:FC = () =&gt; {&lt;br
    return (<br>
        <header><br>
            <nav><br>
                <ul><br>
                    {<br>
                        currentUser.role === "ADMIN" &amp;&amp;<br> &lt;br
                        <li>管理者のみのコンポーネント</li><br>。
                    </li><li> </li><li> </li>&lt;br
                    {<br>
                        currentUser.role === "USER" &amp;&amp;<br> <li>管理者専用コンポーネント</li><br> <li>管理者専用コンポーネント</li><br> <li>管理者専用コンポーネント</li>&lt;br
                        <li>ユーザーのみのコンポーネント</li><br>。
                    }&lt;br
                    {<br>
                        (currentUser.role === "ADMIN" || currentUser.role === "USER") &amp;&amp;&lt;<br> <li>管理者・ユーザー専用コンポーネント</li>&lt;br
                        <li>管理者とユーザーのみのコンポーネント</li><br>。
                    
                    <li>一般的な用法要素</li><br>。
                </ul>&lt;br
            </nav>&lt;br
        </header>&lt;br
    )<br> <br> <li>一般的な利用要素</li><ul><br> </header><br>。
</li><ul><br> </header><br> )<br>
</code></p>
<!-- /wp:paragraph -->

見た目は「悪くない」。おそらく、複雑さを減らすためにチェックを関数にカプセル化できるだろう。 カレントユーザー はあるオブジェクト
それは 役割 しかし、コントロール・メカニズムとして使いたいものであれば、何でも構わない。

このコードにはいくつかの問題がある。もし プロジェクト 成長するにつれて、私たちは多くの場所でその構文を使うようになるだろう。だからコピーする必要がある、
どういうわけか、コンディション。このコードはメンテナンスが難しく、将来的に変更される可能性もある。特に
時間 カレントユーザー を別のものに変える。テストするのはとても難しい。多くのテストを書く必要がある
あなたのコンディションが問題ないかどうかを確認するためにね

簡素化

このコードを少し単純化しよう。いくつかのメソッドを抽出して、コードをより短く、より複雑にすることができる:

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 = () => { { {
return (

{

isAdmin(currentUser.role)&&を返します。
管理者のみのコンポーネント

}
{
isUser(currentUser.role)&&の場合。

ユーザ専用コンポーネント

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

管理者とユーザーのみのコンポーネント

}

一般利用要素

)
}
```

期待できそうだ。繰り返し行のノイズを減らすことができる。コードは読みやすくなり、メンテナンスも容易になる。しかし
機能 isAdminOrUser.我々は2つの役割しか持っていない。もし3つ目のロールを導入するのであれば、別の関数セットを作成する必要があります。
役割を組み合わせた別のバージョンへ。

フィルタリング

関数 ハズロール その代わりとなるのが isX の機能がある。

const hasRole = (role: string, requiredRole: string[]): boolean => { 以下のようになります。
let found: string | undefined = requiredRole.find(s => role === s);
return found !== undefined;
}

export const FilteringAppHeader:FC = () => {
return (

{

hasRole(currentUser.role, ["ADMIN"]) && (管理者専用コンポーネント)
管理者のみのコンポーネント

}
{
hasRole(currentUser.role, ["USER"]) &&管理者専用コンポーネント } {管理者のみ

ユーザのみのコンポーネント

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

管理者とユーザーのみのコンポーネント

}

一般利用要素

)
}
```

これで見た目は良くなった。コードのhtml部分にはまだ条件があるが、これでテストできるようになった。 ハズロール その機能と信頼
は正しいパラメータセットで使用されます。ロールの追加や変更が簡単になりました。すべての
我々が必要としている役割だ。

しかし、この解決策は カレントユーザー オブジェクトにアクセスできます。前提として、オブジェクトは何らかの形でグローバルであるか、あるいは
アプリケーションのどこにでも。だから、これをカプセル化することができる。もちろん、これを ハズロール 関数である:

 const hasRole = (requiredRole: string[]): boolean => { 以下のようになります。
     let found: string | undefined = requiredRole.find(s => currentUser.role === s);
     return found !== undefined;
 }

しかし、それではほとんど何も得られない。

について ガード コンポーネント

ロジック全体をカプセル化するコンポーネントを作る時が来た。名前は ガード そして、このように使いたい。

 export const GuardedAppHeader:FC = () => {
     return (
         <ヘッダー
             
    が必要です。
  • 管理者のみのコンポーネント
  • 。 </ガード
  • ユーザー専用コンポーネント
  • </ガード
  • ユーザーのみのコンポーネント
  • 。 </ガード
  • 管理者とユーザーのみのコンポーネント
  • </ガード
  • 管理者とユーザーのコンポーネント
  • 。 </ガード
  • 一般的な使用要素
  • </ul
); }

コンポーネントには2つの特性が必要だ。まず 子供たち 保護されているコンテンツに責任がある。第二 必須ロール その
アクセス権を与える役割の配列を扱う。

この構造体の表現が必要だ。それは非常に簡単である。型 React.小道具の子供たち それは 子供たち
プロパティを使用します。もちろん、手動でそのプロパティをタイプに追加し、拡張子を省略することもできる。

interface IGuardProps extends React.PropsWithChildren { インターフェース IGuardProps.
requiredRoles: string[];
}

コンポーネント自体もシンプルだ。私たちは ハズロール 関数はここにある。

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)) { { if (hasRole(props.requiredRoles))
    return (
        
            {props.children}
        
    );
} else {
    return ;
}
}
"`

ここで止めることもできるが、簡単すぎるだろう。今、私たちはコンポーネントを持っている。

ガードサービス

最初のステップはチェックの外部化である。 カレントユーザー はハードコードされた値です。この値をカプセル化したい。
ロールの検証方法を "知っている "何らかのサービスに。技術的には ハズロール 関数を別の
クラスである。

シンプルなインターフェースを作る IGuardService という1つのプロパティしか持たない。 ハズロール.

エクスポート・インターフェース IGuardService {
checkRole: (roles: string[]) => boolean;
}

簡単な実装は次のようになる。

class SimpleGuard implements IGuardService { (クラスSimpleGuardはIGuardServiceを実装する)
checkRole(roles: string[]): boolean { 次のようにします。
let found: string | undefined = roles.find(e => e === currentUser.role);
return found !== undefined;
}
}

これを使うには、次のように変更する必要がある。 IGuardProperties とユースケース。

export interface IGuardProps extends React.PropsWithChildren { 次のようになります。
requiredRoles: string[];
guardService:IGuardService;
}

// ...

const AppHeader:FC = () => {
const guardService = new SimpleGuard();
return (

管理者専用コンポーネント
 

ユーザ専用コンポーネント

管理者とユーザーのコンポーネント
 
 

一般利用要素

 

);
}
```

今のコンポーネントはこうだ:

 export const Guard = (props: IGuardProps) => { if (props.guardService.checkRole(props.requiredRoles))
     if (props.guardService.checkRole(props.requiredRoles)) { (props.guardService.checkRole(props.requiredRoles))
         return (
             
                 {props.children}を返します。
             
         );
     } else {
         return ;
     }
 }
 

ずっといい。 ガードサービス 役割をチェックするロジックから私たちを切り離す。私たちは
コンポーネントを使用する。一般的なユースケースは、テストではモックを使い、本番コードではいくつかの "本物の "実装を使うというものだ。

禁止要素

次の改善点は、カスタムの取り扱いだ。 禁止 要素を表示します。現在の解決策は、空の要素をレンダリングします。まず
変更 IGuardProps その要素をレンダリングする関数を追加する。

 export interface IGuardProps extends React.PropsWithChildren {.
     requiredRoles: string[];
     guardService:IGuardService;
     forbidden?: () => React.ReactNode;
 }

これはオプションのプロパティで、名前はクエスチョンマークで終わります。つまり、関数または 未定義.我々は、次のことが必要だ。
で処理する。 ガード コンポーネントを使用している。

export const Guard = (props: IGuardProps) => { もし (props.guardService.checkRole(props.requiredRoles))
if (props.guardService.checkRole(props.requiredRoles)) { (props.guardService.checkRole(props.requiredRoles))
return (

{props.children}を返します。

);
} else if (props.forbidden === undefined) { {.
return ;
} else {
return ()
{props.forbidden()}を返します。

);
}
}

// ...

export const AppHeader:FC = () => {
const guardService = new SimpleGuard();
return (

管理者専用コンポーネント
 

ユーザ専用コンポーネント

禁止 - モデレーターのみ閲覧可
}>
 

モデレーターコンポーネント

 

管理者とユーザーのコンポーネント
 
 

一般利用要素

 

);
}
```

タイプの柔軟性

最後の大きな変化の時です。現バージョンのコンポーネントは ストリング.私たちは、複数の異なる
チェックしたいプロパティのタイプ。数字やカスタム・タイプは特別なものではない。ジェネリックのサポートを追加します。

最初のステップは IGuardService インタフェースを実装する。実装はテストされる値のタイプに依存する。それは
だから、インターフェイスがそれを処理するべきだ。

 export interface IGuardService { 次のようにします。
     checkRole: (roles: ROLE[]) => boolean;
 }

の配列を取るようになった。 役割 ジェネリック型。私たちの単純な実装は少し変わる。

 class SimpleGuard implements IGuardService { 次のようになります。
     checkRole(roles: string[]): boolean { 次のようにします。
         let found: string | undefined = roles.find(e => e === currentUser.role);
         return found !== undefined;
     }
 }

型パラメータを追加する必要があるが、以下のような実装を用意することもできる。 イロール インターフェイスを使用している。

インターフェース IRole {
name: 文字列;
}

//...
class RoleGuardService implements IGuardService { {...
checkRole(roles: IRole[]): boolean {.
let found:IRole | undefined = roles.find(e => e === userWithRole.role);
return found !== undefined;
}
}
```

第二のステップは、この変更を IGuardProps.

 interface IGuardProps extends React.PropsWithChildren {.
     requiredRoles:ROLE[];
     guardService:IGuardService;
     forbidden?: () => React.ReactNode;
 }

そしてそれぞれ ガード コンポーネントを使用している。

export const Guard = (props: IGuardProps) => { もし(props.guardService.checkRole(props.requiredRoles))であれば
     if (props.guardService.checkRole(props.requiredRoles)) { { (props.guardService.checkRole(props.requiredRoles))
         return (
             
                 {props.children}を返します。
             
         );
     } else if (props.forbidden === undefined) { {.
         return ;
     } else {
         return ()
                 {props.forbidden()}を返します。
             
         );
     }
 }

使用例

export const AppHeader:FC = () =&gt; {
     const guardService = new SimpleGuard();
     const roleService = new RoleGuardService();
     return (
         <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}
                                    禁止={() =&gt; <div>禁止 - モデレーターのみ閲覧可</div>}>
                         <li>モデレーターコンポーネント</li>
                     </Guard>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt; ガードサービス。
                         <li>管理者とユーザーのコンポーネント</li>
                     </Guard>
                     <li>一般的な使用要素</li>
                 </ul>
             </nav>
         </header>
     );
 }

この例では IGuardservice これは説明のためである。実際の使用例では
おそらく1つしか使わないだろう。

専用コンポーネントとネスティング

について ガード をネストすることができる。ただ、アクセスはほとんどの外部インスタンスから順番に解決されることを覚えておいてほしい。

export const NestAppHeader:FC = () =&gt; {
     const guardService = new SimpleGuard();
     return (
         <header>
             <nav>
                 <ul>
                     <Guard<string&gt; requiredRoles={["USER", "ADMIN"]} guardService={guardService}&gt; ガードサービス。
                         <Guard<string&gt; requiredRoles={["ADMIN"]}ガードサービス={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}
                                        禁止={() =&gt; <div>禁止 - モデレーターのみ閲覧可</div>}>
                             <li>モデレーターコンポーネント</li>
                         </Guard>
                     </Guard>
                     <li>一般的な使用要素</li>
                 </ul>
             </nav>
         </header>
     );
 }

上記の例では モデレーターコンポーネント なぜなら、ユーザーは1つの役割しか扱えないからである。最初に ガード 制限
役割 アドミン そして ユーザーだから モデレーター がファーストチェックを通過することはない。

私たちは、いくつかのプロパティを非表示にする特殊なコンポーネントを構築することができます。

export const AdminGuard = (props: Omit) => { {.
return   {
const guardService = new SimpleGuard();
return (

管理者専用コンポーネント
 

 管理者専用コンポーネント
ユーザ専用コンポーネント


禁止 - モデレータのみ閲覧可
}>

モデレーターコンポーネント

 ガード。

管理者とユーザーのコンポーネント

 

一般利用要素

);
}
```

この場合 アドミンガード 定義する アドミン の役割を果たす。結果的に、私たちは 役割 タイプ
パラメータが必要だ。

まとめ

この記事では、次のような方法を紹介する。 ガード Reactのコンポーネント.私たちは、複雑なコードから始めます。
を読み、維持します。私たちはそれをより開発しやすい状態に進化させ、カスタム機能コンポーネントを導入します。次に
コンポーネントを拡張して機能を追加し、抽出サービスをリファクタリングし、最後にジェネリック型を追加する。

最終的に、テストと保守が容易なネスト可能なコンポーネントができた。

関連記事

ソフトウェア開発

Reactの長所と短所

なぜReactを使う価値があるのか?このJavaScriptライブラリにはどんな利点があるのか?その答えを見つけるために、この記事に飛び込んで、Reactを使う本当の利点を発見してください。

The Codest
セザリー・ゴラルスキー Software Engineer

ナレッジベースを購読して、IT部門の専門知識を常に最新の状態に保ちましょう。

    会社概要

    The Codest - ポーランドに技術拠点を持つ国際的なソフトウェア開発会社。

    イギリス - 本社

    • オフィス 303B, 182-184 High Street North E6 2JA
      イギリス、ロンドン

    ポーランド - ローカル・テック・ハブ

    • ファブリチュナ・オフィスパーク、アレハ
      ポコジュ18、31-564クラクフ
    • ブレイン・エンバシー, コンストルクトースカ
      11, 02-673 Warsaw, Poland

      The Codest

    • ホーム
    • 会社概要
    • サービス
    • Case Studies
    • ノウハウ
    • 採用情報
    • 辞書

      サービス

    • アドバイザリー
    • ソフトウェア開発
    • バックエンド開発
    • フロントエンド開発
    • Staff Augmentation
    • バックエンド開発者
    • クラウドエンジニア
    • データエンジニア
    • その他
    • QAエンジニア

      リソース

    • 外部ソフトウェア開発パートナーとの協力に関する事実と神話
    • 米国から欧州へ:アメリカの新興企業がヨーロッパへの移転を決断する理由
    • テックオフショア開発ハブの比較:テックオフショア ヨーロッパ(ポーランド)、ASEAN(フィリピン)、ユーラシア(トルコ)
    • CTOとCIOの課題は?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • ウェブサイト利用規約

    著作権 © 2025 by The Codest。無断複写・転載を禁じます。

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