React で再利用可能なラップコンポーネントを作成:カスタムフックを使ったスマートな方法
React コンポーネントを条件付きでラップする方法
3 つの一般的な方法
React コンポーネントを条件付きでラップするには、いくつかの方法があります。最も一般的な方法は次の 3 つです。
三項演算子を使用する
これは、最も簡潔でわかりやすい方法です。次のようなコードになります。
const MyComponent = ({ isLoggedIn, children }) => {
return (
isLoggedIn ? (
<Wrapper>{children}</Wrapper>
) : (
<Default>{children}</Default>
)
);
};
このコードでは、isLoggedIn
プロップが true
の場合、Wrapper
コンポーネントで子コンポーネントをラップします。そうでない場合は、Default
コンポーネントでラップします。
React.Fragment を使用する
React.Fragment
を使用すると、条件付きでレンダリングされる要素をグループ化できます。次のようなコードになります。
const MyComponent = ({ isLoggedIn, children }) => {
return (
<>
{isLoggedIn && <Wrapper>{children}</Wrapper>}
{!isLoggedIn && <Default>{children}</Default>}
</>
);
};
このコードは、三項演算子を使用するコードとほぼ同じですが、より読みやすく、ネストを減らすことができます。
カスタムフックを使用する
カスタムフックを使用して、条件付きラップロジックを再利用可能にすることができます。次のようなコードになります。
const useConditionalWrapper = (condition, Wrapper) => {
return (children) => {
return condition ? <Wrapper>{children}</Wrapper> : children;
};
};
const MyComponent = () => {
const isLoggedIn = useReducer(...); // ログイン状態を管理する reducer
const ConditionalWrapper = useConditionalWrapper(isLoggedIn, Wrapper);
return (
<ConditionalWrapper>
{/* 子コンポーネント */}
</ConditionalWrapper>
);
};
このコードでは、useConditionalWrapper
カスタムフックを使用して、条件付きラップロジックをカプセル化します。このフックは、condition
と Wrapper
コンポーネントを受け取り、子コンポーネントを条件付きでラップする関数 (children
) を返します。
どの方法を使用するべきか?
使用する方法は、要件と好みによって異なります。
- 条件付きラップロジックを再利用可能にしたい場合は、カスタムフックを使用します。
- コードをより読みやすく、ネストを減らしたい場合は、
React.Fragment
を使用します。 - 簡潔でわかりやすい方法が必要な場合は、三項演算子を使用します。
const MyComponent = ({ isLoggedIn, children }) => {
return (
isLoggedIn ? (
<Wrapper>{children}</Wrapper>
) : (
<Default>{children}</Default>
)
);
};
const MyComponent = ({ isLoggedIn, children }) => {
return (
<>
{isLoggedIn && <Wrapper>{children}</Wrapper>}
{!isLoggedIn && <Default>{children}</Default>}
</>
);
};
const useConditionalWrapper = (condition, Wrapper) => {
return (children) => {
return condition ? <Wrapper>{children}</Wrapper> : children;
};
};
const MyComponent = () => {
const isLoggedIn = useReducer(...); // ログイン状態を管理する reducer
const ConditionalWrapper = useConditionalWrapper(isLoggedIn, Wrapper);
return (
<ConditionalWrapper>
{/* 子コンポーネント */}
</ConditionalWrapper>
);
};
使用例
const Wrapper = () => <div style={{ border: '1px solid red' }}>Wrapper</div>;
const Default = () => <div>Default</div>;
const MyComponent = () => {
const isLoggedIn = true;
return (
<MyComponent isLoggedIn={isLoggedIn}>
{/* 子コンポーネント */}
<h1>Hello, World!</h1>
</MyComponent>
);
};
このコードでは、MyComponent
コンポーネントは isLoggedIn
プロップが true
であるため、Wrapper
コンポーネントでラップされます。
- 詳細については、React 公式ドキュメントを参照してください。
- 条件付きラップ以外にも、React コンポーネントを再利用するための様々な方法があります。
React.memo とカスタムフックを使用する
React.memo
とカスタムフックを使用して、パフォーマンスを向上させることができます。次のようなコードになります。
const useConditionalWrapper = (condition, Wrapper) => {
const memoizedWrapper = React.memo(Wrapper);
return (children) => {
return condition ? <memoizedWrapper>{children}</memoizedWrapper> : children;
};
};
const MyComponent = () => {
const isLoggedIn = useReducer(...); // ログイン状態を管理する reducer
const ConditionalWrapper = useConditionalWrapper(isLoggedIn, Wrapper);
return (
<ConditionalWrapper>
{/* 子コンポーネント */}
</ConditionalWrapper>
);
};
このコードでは、useConditionalWrapper
カスタムフックを使用して、条件付きラップロジックをカプセル化します。このフックは、React.memo
を使用して Wrapper
コンポーネントをメモ化し、パフォーマンスを向上させます。
renderProps を使用する
renderProps
を使用すると、ラップコンポーネントにレンダリングされる子コンポーネントを制御できます。次のようなコードになります。
const MyComponent = ({ isLoggedIn, children }) => {
if (isLoggedIn) {
return <Wrapper render={children} />;
}
return <Default>{children}</Default>;
};
このコードでは、MyComponent
コンポーネントは isLoggedIn
プロップと children
プロップを受け取ります。isLoggedIn
が true
の場合、コンポーネントは Wrapper
コンポーネントに render
プロップとして子コンポーネントをレンダリングします。そうでない場合は、Default
コンポーネントにレンダリングします。
context を使用する
context
を使用すると、コンポーネントツリー全体で状態を共有できます。次のようなコードになります。
const AuthContext = React.createContext();
const AuthProvider = ({ children }) => {
const isLoggedIn = useReducer(...); // ログイン状態を管理する reducer
return (
<AuthContext.Provider value={isLoggedIn}>
{children}
</AuthContext.Provider>
);
};
const MyComponent = () => {
const isLoggedIn = useContext(AuthContext);
if (isLoggedIn) {
return <Wrapper />;
}
return <Default />;
};
このコードでは、AuthContext
というコンテキストを作成します。AuthProvider
コンポーネントは、isLoggedIn
状態を value
プロップとしてコンテキストに提供します。MyComponent
コンポーネントは、useContext
フックを使用してコンテキストから isLoggedIn
状態にアクセスできます。
- コンポーネントツリー全体で状態を共有する必要がある場合は、
context
を使用します。 - ラップコンポーネントにレンダリングされる子コンポーネントを制御する必要がある場合は、
renderProps
を使用します。 - パフォーマンスが重要の場合は、
React.memo
とカスタムフックを使用します。
javascript reactjs