Reactコンポーネントが表示されない|よくある原因10選
Reactコンポーネントが表示されない原因と解決方法を解説。初心者がつまずきやすい問題を10個厳選して対処法を紹介します。
Reactコンポーネントが表示されない|よくある原因10選
みなさん、Reactでコンポーネントを作ったのに「あれ?画面に何も表示されない」という経験はありませんか?
「コードは書いたのに、なぜか表示されない」 「エラーも出ないし、何が原因なのかわからない」
そんな悩みを抱えているのではないでしょうか。
実は、Reactコンポーネントが表示されない原因は、パターンが決まっているんです。 小さなミスが原因で起こることが多いですが、原因さえわかれば簡単に解決できます。
大丈夫です! 今回は、初心者の方がよくつまずく10の原因を厳選して、わかりやすく解説します。
この記事を読めば、トラブルが起きても素早く解決できるようになりますよ。 一緒に見ていきましょう!
1. exportとimportの問題
コンポーネントが表示されない原因で最も多いのが、exportとimportの設定ミスです。
これは本当によくある問題なんです。 コンポーネントを作っても、他のファイルから読み込めないと表示されません。
デフォルトエクスポートの問題
まず、よくある間違いから見てみましょう。
// ❌ exportを忘れている
function MyComponent() {
return <div>Hello World</div>;
}
この書き方だと、MyComponent
をexportしていないので、他のファイルから使えません。
正しい書き方はこちらです。
// ✅ デフォルトエクスポート
export default function MyComponent() {
return <div>Hello World</div>;
}
export default
をつけることで、このコンポーネントを他のファイルから使えるようになります。
または、こんな書き方もできます。
function MyComponent() {
return <div>Hello World</div>;
}
export default MyComponent;
関数を定義してから、最後にexport default
で出力する方法ですね。
どちらの書き方でも同じ効果があります。
名前付きエクスポートとの混同
次に、よく混同される「名前付きエクスポート」の問題を見てみましょう。
// ❌ 名前付きエクスポートをデフォルトimportしている
// MyComponent.js
export function MyComponent() {
return <div>Hello World</div>;
}
// App.js
import MyComponent from './MyComponent'; // エラーが発生
この例では、MyComponent
を名前付きエクスポートで出力しているのに、デフォルトimportで読み込もうとしています。
正しい読み込み方法はこちらです。
// ✅ 正しいimport方法
import { MyComponent } from './MyComponent';
名前付きエクスポートの場合は、{}
で囲んで読み込む必要があります。
ポイント:
export default
で出力→import Component from
で読み込みexport function
で出力→import { Component } from
で読み込み
export方法とimport方法を必ず一致させましょう。
2. JSXのreturn文の問題
JSXの書き方で間違いがあると、コンポーネントが表示されません。
特に、return文に関するミスが多いんです。
return文を書き忘れ
初心者の方がよくやってしまう間違いです。
// ❌ return文がない
function MyComponent() {
<div>Hello World</div>; // returnがない
}
この書き方だと、JSXが返されないので何も表示されません。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent() {
return <div>Hello World</div>;
}
return
をつけることで、JSXが正しく返されます。
関数コンポーネントでは、必ずJSXをreturnする必要があります。
複数要素のreturn
複数の要素を返そうとして、エラーになることもあります。
// ❌ 複数の要素をreturnしている
function MyComponent() {
return (
<div>First</div>
<div>Second</div> // エラーが発生
);
}
Reactでは、複数の要素を直接returnできません。
正しい書き方はこちらです。
// ✅ フラグメントを使った書き方
function MyComponent() {
return (
<>
<div>First</div>
<div>Second</div>
</>
);
}
<>
と</>
で囲むことで、複数の要素をまとめて返せます。
これをフラグメントといいます。
親要素で囲む方法もあります。
// ✅ 親要素で囲む方法
function MyComponent() {
return (
<div>
<div>First</div>
<div>Second</div>
</div>
);
}
どちらの方法でも問題ありません。 状況に応じて使い分けてください。
3. 条件分岐でのrender問題
条件分岐の書き方が間違っていると、コンポーネントが表示されません。
これも初心者の方がよくつまずくポイントです。
条件分岐の書き方ミス
よくある間違いを見てみましょう。
// ❌ 条件分岐の書き方が間違っている
function MyComponent({ isVisible }) {
if (isVisible) {
<div>Visible</div>; // returnがない
}
return <div>Not visible</div>;
}
if
文の中でも、return
を忘れずに書く必要があります。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent({ isVisible }) {
if (isVisible) {
return <div>Visible</div>;
}
return <div>Not visible</div>;
}
条件分岐の中でも、必ずreturn
を書きましょう。
論理演算子の使用ミス
&&
演算子を使った条件分岐でも、注意が必要です。
// ❌ 予期しない値がレンダリングされる
function MyComponent({ count }) {
return (
<div>
{count && <div>Count: {count}</div>}
</div>
);
}
この書き方だと、count
が0
の場合に「0」が画面に表示されてしまいます。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent({ count }) {
return (
<div>
{count > 0 && <div>Count: {count}</div>}
</div>
);
}
count > 0
のように、必ずboolean値を返すようにしましょう。
ポイント:
&&
演算子の左側は、true
またはfalse
を返す式にする- 数値の
0
や空文字""
は、画面に表示されてしまう
4. propsの受け渡し問題
propsの受け渡しで問題があると、コンポーネントが正しく表示されません。
特に、propsの受け取り方でミスが起こりやすいんです。
propsを受け取れていない
よくある間違いから見てみましょう。
// ❌ propsを受け取れていない
function MyComponent() {
return <div>{title}</div>; // titleが未定義
}
この書き方だと、title
が未定義なので何も表示されません。
正しい書き方はこちらです。
// ✅ propsを分割代入で受け取る
function MyComponent({ title }) {
return <div>{title}</div>;
}
{title}
のように、分割代入でpropsを受け取ります。
または、このような書き方もできます。
// ✅ propsオブジェクトで受け取る
function MyComponent(props) {
return <div>{props.title}</div>;
}
props.title
のように、propsオブジェクトからアクセスする方法ですね。
propsが渡されていない
今度は、propsを渡し忘れるパターンです。
// ❌ propsが渡されていない
function App() {
return <MyComponent />; // titleが渡されていない
}
function MyComponent({ title }) {
return <div>{title}</div>; // undefinedが表示される
}
この場合、title
はundefined
になってしまいます。
正しい書き方はこちらです。
// ✅ propsを正しく渡す
function App() {
return <MyComponent title="Hello World" />;
}
function MyComponent({ title }) {
return <div>{title}</div>;
}
必要なpropsは確実に渡すようにしましょう。
ポイント:
- コンポーネントに必要なpropsを把握する
- propsの名前を間違えないようにする
- デフォルト値を設定しておくと安心
5. 状態管理の問題
useState
などの状態管理で問題があると、コンポーネントが正しく表示されません。
特に、状態の初期値に関する問題が多いんです。
状態の初期値が原因
よくある間違いを見てみましょう。
// ❌ 状態の初期値が原因で表示されない
function MyComponent() {
const [user, setUser] = useState(); // 初期値がundefined
return (
<div>
<h1>{user.name}</h1> {/* userがundefinedでエラー */}
</div>
);
}
この書き方だと、user
がundefined
なので、user.name
にアクセスできません。
結果として、エラーが発生してコンポーネントが表示されません。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent() {
const [user, setUser] = useState(null);
if (!user) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{user.name}</h1>
</div>
);
}
user
がnull
の場合は、「Loading...」を表示します。
データが読み込まれるまでの間、何かを表示しておくことが重要です。
非同期処理での状態更新
API呼び出しなどの非同期処理でも問題が起こることがあります。
// ❌ 非同期処理で状態が更新されない
function MyComponent() {
const [data, setData] = useState([]);
useEffect(() => {
fetchData().then(result => {
setData(result);
});
}, []);
return (
<div>
{data.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
この書き方だと、エラーが発生した場合に何も表示されません。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchData()
.then(result => {
setData(result);
setLoading(false);
})
.catch(error => {
console.error(error);
setLoading(false);
});
}, []);
if (loading) {
return <div>Loading...</div>;
}
return (
<div>
{data.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
loading
状態を追加して、データを取得中は「Loading...」を表示します。
エラーが発生した場合も、適切に処理します。
ポイント:
- 状態の初期値を適切に設定する
- データがない場合の表示を考慮する
- 非同期処理のエラーハンドリングを行う
6. コンポーネントの呼び出し方法
コンポーネントの呼び出し方が間違っていると、正しく表示されません。
これも初心者の方がよく間違えるポイントです。
関数として呼び出している
よくある間違いを見てみましょう。
// ❌ 関数として呼び出している
function App() {
return (
<div>
{MyComponent()} {/* 間違い */}
</div>
);
}
この書き方だと、MyComponent
を普通の関数として呼び出しています。
正しい書き方はこちらです。
// ✅ JSXタグとして使用
function App() {
return (
<div>
<MyComponent /> {/* 正しい */}
</div>
);
}
Reactコンポーネントは、JSXタグとして使用する必要があります。
<MyComponent />
のように、HTMLタグのような書き方をします。
大文字小文字の問題
コンポーネント名の大文字小文字も重要です。
// ❌ 小文字で始まっている
function myComponent() {
return <div>Hello World</div>;
}
function App() {
return <myComponent />; // HTMLタグとして認識される
}
コンポーネント名が小文字で始まっていると、Reactは通常のHTMLタグとして認識してしまいます。
正しい書き方はこちらです。
// ✅ 大文字で始まる
function MyComponent() {
return <div>Hello World</div>;
}
function App() {
return <MyComponent />;
}
Reactのルール:
- コンポーネント名は必ず大文字で始める
- JSXタグとして使用する(関数呼び出しではない)
これは、ReactがコンポーネントとHTMLタグを区別するための重要なルールです。
7. useEffectの依存配列問題
useEffect
の依存配列が間違っていると、期待通りに表示されません。
特に、依存配列の設定でミスが起こりやすいんです。
依存配列の設定ミス
よくある間違いを見てみましょう。
// ❌ 依存配列の設定が間違っている
function MyComponent({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
if (userId) {
fetchUser(userId).then(setUser);
}
}, []); // userIdが依存配列に含まれていない
return user ? <div>{user.name}</div> : <div>Loading...</div>;
}
この書き方だと、userId
が変更されてもuseEffect
が再実行されません。
結果として、古いデータが表示されたままになってしまいます。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
if (userId) {
fetchUser(userId).then(setUser);
}
}, [userId]); // userIdを依存配列に含める
return user ? <div>{user.name}</div> : <div>Loading...</div>;
}
[userId]
のように、useEffect
内で使用する値を依存配列に含めます。
重要なポイント:
useEffect
内で使用するすべての値を依存配列に含める- propsや状態も忘れずに含める
- 依存配列が空
[]
の場合は、マウント時に1回だけ実行される
これにより、userId
が変更されるたびに新しいユーザー情報が取得されます。
8. keyプロパティの問題
リストをレンダリングする際のkey
プロパティの問題も、表示に影響します。
特に、keyの設定でミスが起こりやすいんです。
keyプロパティの設定不備
よくある間違いを見てみましょう。
// ❌ keyプロパティが設定されていない
function MyComponent({ items }) {
return (
<div>
{items.map(item => (
<div>{item.name}</div> // keyがない
))}
</div>
);
}
この書き方だと、Reactが要素を正しく追跡できません。 結果として、リストの更新が正しく行われない場合があります。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent({ items }) {
return (
<div>
{items.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
key={item.id}
のように、一意の値をkeyとして設定します。
不適切なkeyの使用
インデックスをkeyに使うのは推奨されません。
// ❌ インデックスをkeyに使用(推奨されない)
function MyComponent({ items }) {
return (
<div>
{items.map((item, index) => (
<div key={index}>{item.name}</div>
))}
</div>
);
}
インデックスをkeyに使うと、リストの順序が変わった時に問題が起こります。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent({ items }) {
return (
<div>
{items.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
可能な限り、一意で安定したIDをkeyとして使用しましょう。
ポイント:
- 配列をレンダリングする際は必ずkeyを設定する
- keyには一意で安定した値を使う
- インデックスの使用は避ける
9. CSSの問題
意外と見落としがちなのが、CSSが原因でコンポーネントが見えないケースです。
コンポーネントは正しく動作しているのに、CSSで非表示にされている場合があります。
display: noneの設定
よくある問題を見てみましょう。
/* ❌ CSSで非表示にされている */
.my-component {
display: none;
}
function MyComponent() {
return (
<div className="my-component">
Hello World
</div>
);
}
この場合、コンポーネントは正常に動作していますが、CSSでdisplay: none
が設定されているため見えません。
確認方法:
- ブラウザの開発者ツールでHTML要素を確認する
- CSSの
display
プロパティをチェックする - 一時的にクラス名を削除して確認する
透明度の問題
透明度が原因で見えない場合もあります。
/* ❌ 透明度が0に設定されている */
.my-component {
opacity: 0;
}
opacity: 0
が設定されていると、コンポーネントは存在しているのに見えません。
チェックポイント:
display: none
やvisibility: hidden
の設定opacity: 0
の設定height: 0
やwidth: 0
の設定position: absolute
による画面外への配置
これらの設定がないか確認してみてください。
10. パフォーマンス最適化の問題
React.memo
やuseMemo
などの最適化機能が原因で、コンポーネントが更新されない場合があります。
これは少し上級者向けの問題ですが、知っておくと役立ちます。
React.memoの依存関係
よくある間違いを見てみましょう。
// ❌ React.memoの比較関数が間違っている
const MyComponent = React.memo(function MyComponent({ data }) {
return <div>{data.name}</div>;
}, (prevProps, nextProps) => {
return true; // 常にtrueを返すため、再レンダリングされない
});
この書き方だと、propsが変更されても再レンダリングされません。
正しい書き方はこちらです。
// ✅ 正しい書き方
const MyComponent = React.memo(function MyComponent({ data }) {
return <div>{data.name}</div>;
}, (prevProps, nextProps) => {
return prevProps.data.name === nextProps.data.name;
});
比較関数では、propsが同じ場合にtrueを返します。 異なる場合はfalseを返して、再レンダリングを促します。
useMemoの依存配列
useMemo
の依存配列の設定ミスも問題になります。
// ❌ useMemoの依存配列が間違っている
function MyComponent({ items }) {
const filteredItems = useMemo(() => {
return items.filter(item => item.active);
}, []); // itemsが依存配列に含まれていない
return (
<div>
{filteredItems.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
この書き方だと、items
が変更されてもfilteredItems
が更新されません。
正しい書き方はこちらです。
// ✅ 正しい書き方
function MyComponent({ items }) {
const filteredItems = useMemo(() => {
return items.filter(item => item.active);
}, [items]); // itemsを依存配列に含める
return (
<div>
{filteredItems.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
[items]
のように、計算で使用する値を依存配列に含めます。
ポイント:
- 最適化機能は正しく使わないと逆効果
- 依存配列の設定は慎重に行う
- 問題が起きたら、一時的に最適化を外して確認する
効果的なデバッグ方法
コンポーネントが表示されない時のデバッグ方法をご紹介します。
これらの方法を覚えておくと、問題を素早く発見できます。
console.logでの確認
まず、基本的なデバッグ方法から見てみましょう。
function MyComponent({ data }) {
console.log('MyComponent rendered', data);
if (!data) {
console.log('No data provided');
return <div>No data</div>;
}
return <div>{data.name}</div>;
}
console.log
を使って、以下を確認できます。
チェックポイント:
- コンポーネントがレンダリングされているか
- propsが正しく渡されているか
- 条件分岐が正しく動作しているか
ブラウザの開発者ツールのコンソールを見れば、ログが表示されます。
React Developer Tools
React Developer Toolsは、Reactアプリのデバッグに必須のツールです。
Chrome拡張機能として無料で使用できます。
確認できる内容:
- コンポーネントツリーの構造
- propsの値
- stateの状態
- レンダリングの頻度
これらの情報により、問題の原因を特定しやすくなります。
エラーバウンダリーの実装
エラーが発生した場合に、適切に処理するためのコンポーネントです。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('Component error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return <div>Something went wrong.</div>;
}
return this.props.children;
}
}
このコンポーネントを使うと、エラーが発生してもアプリ全体が停止しません。
function App() {
return (
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);
}
エラーが発生した場合は、「Something went wrong.」が表示されます。
デバッグのコツ:
- 小さな変更から始める
- 一つずつ問題を切り分ける
- エラーメッセージを見逃さない
まとめ
お疲れ様でした! Reactコンポーネントが表示されない原因と解決方法を見てきました。
重要なポイントをおさらいしましょう。
よくある原因:
- export/importの設定ミス
- JSXのreturn文の問題
- 条件分岐とpropsの受け渡し
- 状態管理とuseEffectの設定
- CSSによる非表示
デバッグのポイント:
- console.logで動作を確認
- React Developer Toolsを活用
- エラーメッセージを注意深く読む
これらの問題を一つずつ確認することで、ほとんどのケースで原因を特定できます。
エラーが発生した場合は、焦らずに落ち着いて対処しましょう。 最初は時間がかかるかもしれませんが、慣れてくると素早く解決できるようになります。
ぜひ、今回紹介した内容を参考に、React開発を楽しんでください。 きっと、スムーズなコンポーネント開発ができるようになりますよ!
困った時は、この記事を思い出してくださいね。