日本語版
最新ニュース
科学&テクノロジー

もっと早く知らなかったことを後悔している10のこと

React に圧倒されていると感じている若手開発者は、あなただけではありません。始めたばかりの頃、私はたくさんの間違いを犯しました。最初からこれら 10 のことを知っていれば避けられた間違いです。そういった間違いを回避できるようにお手伝いさせてください。目次1. アプリのパフォーマンスを大幅に向上させる children 小道具の children prop はネストされた要素を渡すためだけのものではありません。 これは、次のような利点がある強力なツールです。プロペラの穴あけを避ける プロパティを親経由でルーティングするのではなく、子コンポーネントに直接渡すことによって。拡張可能なコードを書く 親を変更せずに子コンポーネントを変更することによって。不必要な再レンダリングを避ける 「遅い」コンポーネントの数 (以下の例を参照 👇)。 ❌ 悪い: MyVerySlowComponent いつでもレンダリング Dashboard レンダリングは、現在時刻が更新されるたびに行われます。function App() { // Some other logic… return Dashboard />; } function Dashboard() { const [currentTime, setCurrentTime]…

もっと早く知らなかったことを後悔している10のこと

1736170365
2025-01-06 10:19:00

React に圧倒されていると感じている若手開発者は、あなただけではありません。

始めたばかりの頃、私はたくさんの間違いを犯しました。最初からこれら 10 のことを知っていれば避けられた間違いです。

そういった間違いを回避できるようにお手伝いさせてください。

目次

1. アプリのパフォーマンスを大幅に向上させる children 小道具

children prop はネストされた要素を渡すためだけのものではありません。

これは、次のような利点がある強力なツールです。

  • プロペラの穴あけを避ける プロパティを親経由でルーティングするのではなく、子コンポーネントに直接渡すことによって。

  • 拡張可能なコードを書く 親を変更せずに子コンポーネントを変更することによって。

  • 不必要な再レンダリングを避ける 「遅い」コンポーネントの数 (以下の例を参照 👇)。

悪い: MyVerySlowComponent いつでもレンダリング Dashboard レンダリングは、現在時刻が更新されるたびに行われます。

function App() {
  // Some other logic…
  return Dashboard />;
}

function Dashboard() {
  const [currentTime, setCurrentTime] = useState(new Date());
  useEffect(() => {
    const intervalId = setInterval(() => {
      setCurrentTime(new Date());
    }, 1_000);
    return () => clearInterval(intervalId);
  }, []);

  return (
    
      h1>{currentTime.toTimeString()}h1>
      MyVerySlowComponent />
    >
  );
}

良い: MyVerySlowComponent 不必要に再レンダリングしません。

function App() {
  return (
    Dashboard>
      MyVerySlowComponent />
    Dashboard>
  );
}

function Dashboard({ children }) {
  const [currentTime, setCurrentTime] = useState(new Date());
  useEffect(() => {
    const intervalId = setInterval(() => {
      setCurrentTime(new Date());
    }, 1_000);
    return () => clearInterval(intervalId);
  }, []);

  return (
    
      h1>{currentTime.toTimeString()}h1>
      {children}
    >
  );
}

💡 この画像で最適化の結果を確認できます 👉 ここ

2. 参照と状態をいつ使用するか

Ref は次のような値に最適です。 再レンダリングをトリガーすべきではありません

デフォルトの状態を維持する代わりに、次のように自問してください。 「変更時に再レンダリングをトリガーする必要がありますか?」 答えが「いいえ」の場合は、ref を使用します。

これらは、タイマー、DOM 要素、レンダリング間で持続するが UI には影響しない値など、変更可能な値を追跡するのに最適です。

悪い:保管しております intervalId 状態で。コンポーネントは次の場合に再レンダリングされます。 intervalId UI が同じであっても、状態は変化します。

function Timer() {
  const [time, setTime] = useState(new Date());
  const [intervalId, setIntervalId]= useState();

  useEffect(() => {
    const id = setInterval(() => {
      setTime(new Date());
    }, 1_000);
    setIntervalId(id);
    return () => clearInterval(id);
  }, []);

  const stopTimer = () => {
    intervalId && clearInterval(intervalId);
  };

  return (
    
      Current time: {time.toLocaleTimeString()} >
      button onClick={stopTimer}>Stop timerbutton>
    >
  );
}

良い:保管しております intervalId 参考として。これは、再レンダリングをトリガーする追加の状態がないことを意味します。

function Timer() {
  const [time, setTime] = useState(new Date());
  const intervalIdRef = useRef();
  const intervalId = intervalIdRef.current;

  useEffect(() => {
    const id = setInterval(() => {
      setTime(new Date());
    }, 1_000);
    intervalIdRef.current = id;
    return () => clearInterval(id);
  }, []);

  const stopTimer = () => {
    intervalId && clearInterval(intervalId);
  };

  return (
    
      Current time: {time.toLocaleTimeString()} >
      button onClick={stopTimer}>Stop timerbutton>
    >
  );
}

3. デフォルトのエクスポートよりも名前付きエクスポートを優先する

名前付きエクスポートにより、リファクタリングとデバッグが容易になります。

悪い: 名前を変更するには手動で更新する必要があります。

export default function Button() {}
// Later...
import Button from './Button';

良い: 名前の変更は自動的に行われます。

export function Button() {}
// Later...
import { Button } from './Button';

4. 避ける useEffect 何が何でも

私が対処したアプリのクラッシュはすべてそうでした useEffect コードの中に隠れています😅。

真剣に、避けてください useEffect:

  • これは、過剰なレンダリングや不明瞭なコードなどで確実に終わる方法です。

  • コード フローに従うのが難しくなります

代わりに、それなしで同じ結果を達成できるかどうかを検討してください。

悪い: 電話をかける onToggled 内部 useEffect

function Toggle({ onToggled }) {
    const [on, setOn] = React.useState(false);
    const toggle = () => setOn(!on);
    
    useEffect(() => {
        onToggled(on);
    }, [on]);

    return (
        button onClick={toggle}>
            {on ? 'on' : 'off'}
        button>
    );
}

良い: 電話 onToggled 関連する場合。

function Toggle({ onToggled }) {
    const [on, setOn] = React.useState(false);
    const handleToggle = () => {
        const next = !on;
        setOn(next);
        onToggled(next);
    };
    return (
        button onClick={handleToggle}>
            {on ? 'on' : 'off'}
        button>
    );
}

5. React のライフサイクルを理解する

バグやパフォーマンスの問題を回避するためにライフサイクルの段階を学びます。

  • 取り付け: コンポーネントが最初にレンダリングされるとき。

  • 更新中: 何らかの状態が変化し、React が再レンダリングされるとき。

  • アンマウント中: コンポーネントが DOM から削除されたとき。

6. ESLint を使用して愚かな間違いを追跡する

ESLint を使用すると、特にフックにおける微妙なバグを防ぐことができます。

悪い: 依存関係が欠落しています useEffect

useEffect(() => {
  console.log(data);
}, []); // Missing dependencies!

7. React DevTools を使用してよりスマートにデバッグする

React DevTools は、パフォーマンスの問題をデバッグするのに最適です。 「プロファイラー」タブを使用して、遅いコンポーネントを見つけます。

悪い: のみに依存する console.log アプリが遅い理由を推測するためのタイマー。

良い: プロファイラーを使用して次のことを行います。

💡 このすばらしいツールで使い方を学びましょう ガイド

8. エラー境界を使用して完全なクラッシュを回避する

デフォルトでは、アプリケーションでレンダリング中にエラーが発生すると、UI 全体がクラッシュします。 💥

9. プロのようにコードを整理する

クリーンなコードは保守可能なコードです。

次の簡単なヒントに従ってください。

  • コンポーネントと関連アセット (つまり、スタイル、テストなど) を同じ場所に配置します。

  • ファイルを小さく保ちます。

  • 関連するコンポーネントをフォルダーにグループ化します。

悪い: 削除するときは Button.js、忘れてしまいがちです。 Button.css

src/
  components/
    Button.js
    Modal.js
styles/
  Button.css

良い: 関連ファイルをまとめて保管します。

src/
  components/
    Button/
      Button.js
      Button.css
      Button.test.js

10. React Web サイトには必要なものがすべて揃っています

見落とさないでください 公式 React ドキュメント。 例、説明、ベスト プラクティスが満載です。

悪い: React の基本的な概念を際限なく検索し、古いブログ投稿にたどり着きます。

良い: 公式ドキュメントをブックマークして、行き詰まったときに最初に参照してください。

まとめ

React をマスターするには時間がかかります。

しかし、これらの教訓は、私の初期の間違いからあなたを救うでしょう。

コーディングを続け、好奇心を持ち続けて、覚えておいてください。これは得です。

#もっと早く知らなかったことを後悔している10のこと

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。