この記事では、組み込みコンポーネント、styled-componentsの基本やその他の高度な機能を包括的に理解できます。styled-componentsの概要、インストール方法も解説します。
はじめに
Reactの基礎の記事一覧はクリックすると表示されます。
Reactは、Node.jsが必要です。インストールがまだの方はこちらを確認してください。
開発環境は、VSCodeがおすすめです。
組み込みコンポーネント
Reactには、アプリケーション開発を効率化するための組み込みコンポーネントがいくつか用意されています。
- Fragmentコンポーネントは、複数の要素をグループ化するために使用されます。これにより、不要なDOM要素の追加を避けることができます。
- Suspenseコンポーネントは、非同期操作の結果を待つ間に代替コンテンツを表示するために使用されます。 これは、データフェッチやコード分割と組み合わせて使用されることが多いです。
App.js
import React, { Fragment, Suspense } from 'react';
// Fragmentの使用例
function FragmentExample() {
return (
// Fragmentを使用して複数の要素をグループ化
<Fragment>
<h1>Welcome to My Blog</h1>
<p>This is a paragraph about React components.</p>
<button>Click me!</button>
</Fragment>
);
}
// 非同期コンポーネントをシミュレート
const AsyncComponent = React.lazy(() =>
new Promise(resolve => {
setTimeout(() => {
resolve({ default: () => <div>Async content loaded!</div> });
}, 2000);
})
);
// Suspenseの使用例
function SuspenseExample() {
return (
// Suspenseを使用して非同期コンポーネントをラップ
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent />
</Suspense>
);
}
// メインのアプリコンポーネント
function App() {
return (
<div>
<h2>Fragment Example:</h2>
<FragmentExample />
<h2>Suspense Example:</h2>
<SuspenseExample />
</div>
);
}
export default App;
出力結果:
このコードは、ReactのFragmentとSuspenseコンポーネントの基本的な使用方法を示しています。
- Fragment:
FragmentExample
関数では、Fragment
を使用して複数の要素(h1, p, button)をグループ化しています。- これにより、余分なDOMノードを追加することなく、複数の要素を返すことができます。
- Suspense:
AsyncComponent
は、非同期で読み込まれるコンポーネントをシミュレートしています。実際のアプリケーションでは、これは通常、データフェッチや遅延ロードされるコンポーネントになります。SuspenseExample
関数では、Suspense
コンポーネントを使用してAsyncComponent
をラップしています。fallback
プロップには、非同期コンテンツがロードされるまでの間に表示される内容を指定します。
- App:
- メインの
App
コンポーネントで、両方の例を組み合わせて表示しています。
- メインの
このコードを実行すると、FragmentExampleの内容がすぐに表示され、その後SuspenseExampleの「Loading…」が2秒間表示された後、「Async content loaded!」に置き換わります。これらの組み込みコンポーネントを使用することで、より効率的で柔軟なReactアプリケーションを構築することができます。
コンポーネント開発でのスタイル定義
Reactコンポーネントのスタイリングには複数のアプローチがあります。
styled-componentsのインストール
今回は、styled-componentsライブラリを使用します。
※styled-componentsはプロジェクトのルートディレクトリでインストールしてください。
- コマンドプロンプトもしくは、ターミナルを開きます。
- プロジェクトのルートディレクトリに移動します。
- styled-componentsをインストールします。
npm install styled-components
- インストールが成功したか確認します。
npm list styled-components
- インストールが成功している場合、バージョン情報が表示されます。
styled-components@6.1.13
インストール後、src/package.jsonファイルを確認すると、dependencies(またはdevDependencies)にstyled-componentsが追加されているはずです。
インストール後は、Reactコンポーネント内でimportして使用できるようになります。
スタイリングの実装例
今回は、src/App.module.cssを新たに作成します。
- App.module.css
.cssModulesExample {
color: red;
font-size: 14px;
padding: 10px;
border: 1px solid red;
border-radius: 5px;
margin-bottom: 10px;
}
- App.js
import React from 'react';
// CSS Modulesのスタイルをインポート
import styles from './App.module.css';
// styled-componentsライブラリをインポート
import styled from 'styled-components';
// インラインスタイルの例
function InlineStyleComponent() {
// JavaScriptオブジェクトとしてスタイルを定義
const style = {
color: 'blue',
fontSize: '14px',
padding: '10px',
border: '1px solid blue',
borderRadius: '5px',
marginBottom: '10px'
};
// styleオブジェクトを直接要素に適用
return <div style={style}>インラインスタイルの例</div>;
}
// CSS Modulesの例
function CSSModulesComponent() {
// CSS Modulesで定義されたクラス名を使用
return <div className={styles.cssModulesExample}>CSS Modulesの例</div>;
}
// Styled Componentsの例
// スタイル付きのdiv要素を作成
const StyledDiv = styled.div`
color: green;
font-size: 14px;
padding: 10px;
border: 1px solid green;
border-radius: 5px;
margin-bottom: 10px;
`;
function StyledComponentsExample() {
// 作成したスタイル付きコンポーネントを使用
return <StyledDiv>Styled Componentsの例</StyledDiv>;
}
// メインのAppコンポーネント
function App() {
return (
<div>
<h1>Reactアプリケーションのスタイリング</h1>
{/* 各スタイリング方法の例を表示 */}
<InlineStyleComponent />
<CSSModulesComponent />
<StyledComponentsExample />
</div>
);
}
export default App;
出力結果:
このコードでは:
- インラインスタイル:
InlineStyleComponent
で JavaScript オブジェクトとしてスタイルを直接定義しています。
- CSS Modules:
CSSModulesComponent
で別の CSS ファイル(App.module.css
)からスタイルをインポートして使用しています。
- Styled Components:
StyledComponentsExample
でstyled-components
ライブラリを使用してコンポーネントとスタイルを一緒に定義しています。
各アプローチは少し異なる見た目になり、それぞれの特徴を視覚的に確認できます。このコードを実行すると、3つの異なるスタイリング方法で作成された要素が表示されます。これらの方法を使い分けることで、プロジェクトの要件に応じて最適なスタイリング戦略を選択できます。
コンポーネントその他の機能
エラー境界は、子コンポーネントツリーでJavaScriptエラーをキャッチし、フォールバックUIを表示するコンポーネントです。 これにより、アプリケーション全体がクラッシュするのを防ぐことができます。
- App.js
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
// エラー境界コンポーネント
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// エラーが発生したらステートを更新
return { hasError: true };
}
render() {
if (this.state.hasError) {
// エラーが発生した場合のフォールバックUI
return <h2>申し訳ありません。エラーが発生しました。</h2>;
}
// エラーがない場合は子コンポーネントを表示
return this.props.children;
}
}
// エラーを発生させるコンポーネント
function BuggyCounter() {
const [counter, setCounter] = useState(0);
function handleClick() {
setCounter(prevCounter => {
if (prevCounter > 4) {
// カウンターが5を超えるとエラーを発生させる
throw new Error('カウンターが大きすぎます!');
}
return prevCounter + 1;
});
}
return <button onClick={handleClick}>{counter}回クリックされました</button>;
}
// ポータルを使用するモーダルコンポーネント
function Modal({ children, onClose }) {
return ReactDOM.createPortal(
<div style={{
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
background: 'white',
padding: '20px',
border: '1px solid black'
}}>
{children}
<button onClick={onClose}>閉じる</button>
</div>,
document.body
);
}
// メモ化されたコンポーネント
const ExpensiveComponent = React.memo(function({ text }) {
console.log('ExpensiveComponent がレンダリングされました');
return <p>{text}</p>;
});
// メインのアプリコンポーネント
function App() {
const [showModal, setShowModal] = useState(false);
const [count, setCount] = useState(0);
return (
<div>
<h1>Reactの高度な機能</h1>
<h2>1. エラー境界</h2>
<ErrorBoundary>
<BuggyCounter />
</ErrorBoundary>
<h2>2. ポータル</h2>
<button onClick={() => setShowModal(true)}>モーダルを開く</button>
{showModal && (
<Modal onClose={() => setShowModal(false)}>
<p>これはポータルを使用したモーダルです。</p>
</Modal>
)}
<h2>3. メモ化</h2>
<button onClick={() => setCount(c => c + 1)}>カウント: {count}</button>
<ExpensiveComponent text="この文章は変更されないので、再レンダリングされません。" />
</div>
);
}
export default App;
出力結果:
- コンソール出力画面
このコードは、Reactの3つの高度な機能を示しています:
- エラー境界:
ErrorBoundary
コンポーネントは、子コンポーネントで発生したエラーをキャッチし、フォールバックUIを表示します。BuggyCounter
コンポーネントは、特定の条件でエラーを発生させます。
- ポータル:
Modal
コンポーネントは、ReactDOMのcreatePortalを使用して、コンポーネントをDOM階層の外部(この場合はdocument.body)にレンダリングします。- これにより、モーダルのようなオーバーレイUIを簡単に作成できます。
- メモ化:
ExpensiveComponent
はReact.memo
でラップされており、プロップスが変更されない限り再レンダリングされません。- これにより、不必要な再レンダリングを防ぎ、パフォーマンスを向上させることができます。
このコードを実行すると、各機能のデモを見ることができます。エラー境界はカウンターが5を超えるとエラーメッセージを表示し、ポータルを使用したモーダルを開くことができ、メモ化されたコンポーネントは親コンポーネントが再レンダリングされても更新されないことを確認できます。
これらの高度な機能を理解し適切に使用することで、より堅牢で効率的なReactアプリケーションを構築することができます。
まとめ
- 組み込みコンポーネントは、Reactが提供する特殊な機能を持つコンポーネントです。
- Fragmentコンポーネントは、複数の要素をグループ化し、不要なDOM要素の追加を避けるために使用されます。
- Suspenseコンポーネントは、非同期操作の結果を待つ間に代替コンテンツを表示するために使用されます。
- styled-componentsは、Reactコンポーネントと密接に統合されたスタイリングを可能にします。
- エラー境界は、子コンポーネントで発生したエラーをキャッチし、フォールバックUIを表示するコンポーネントです。
組み込みコンポーネントとエラー境界は、Reactアプリケーションの開発において重要な役割を果たします。これらを使用することで、コードの効率性と可読性が向上し、より堅牢なアプリケーションを構築できます。
また、styled-componentsは、Reactアプリケーションのスタイリングを効率的かつ管理しやすくするツールです。コンポーネントベースの開発に適しており、スタイルの再利用性と保守性を高めることができます。また、JavaScriptの機能を活用した動的なスタイリングが可能なため、より柔軟なデザイン実装が可能になります。
コメント