ホームページ >ウェブフロントエンド >jsチュートリアル >Redux について: 初心者向けの総合ガイド

Redux について: 初心者向けの総合ガイド

王林
王林オリジナル
2024-08-24 11:06:02834ブラウズ

Understanding Redux: A Beginner

はじめに: Redux とは何ですか? なぜ Redux が必要なのでしょうか?

Web アプリケーションが複雑になるにつれて、状態の管理はますます困難になります。予測不可能な状態変化や追跡が難しいデータ フローの網に巻き込まれたことがある人は、あなただけではありません。ここで Redux が救世主として登場します。

Redux は JavaScript アプリケーション用の状態管理ライブラリであり、特に React と併用した場合にその効果が高いことで知られています。 Redux は、アプリケーションの状態を管理する予測可能かつ一元的な方法を提供することで、時間の経過とともにデータがどのように変化するか、またアプリケーションのさまざまな部分がどのように相互作用するかを追跡するプロセスを簡素化します。

しかし、なぜ Redux が必要なのでしょうか?大規模なアプリケーションでは、状態の変更が複数の場所で発生する可能性があるため、特定のデータがどこでどのように変更されたかを特定することが困難になります。このようなアプリケーションのデバッグと保守は悪夢になる可能性があります。 Redux は、アプリケーション全体の状態をストアと呼ばれる単一の集中場所に保存することで、これらの課題に対処します。この一元化されたアプローチにより、状態管理が簡素化されるだけでなく、アプリケーションの予測可能性とテスト可能性も強化されます。

このガイドでは、Redux の中心となる概念の理解から、React アプリケーションでの設定と使用まで、Redux を詳しく説明します。この記事を読み終えるまでに、Redux をしっかりと理解し、それをプロジェクトに適用する準備が整っていることでしょう。

Redux の中心的な概念

Redux を真に理解するには、ストア、アクション、リデューサーという 3 つの基本概念を理解することが不可欠です。これらの各概念をさらに詳しく見てみましょう。

1. ストア: 唯一の真実の情報源

Redux の中心には、アプリケーションの状態全体を保持する集中リポジトリであるストアがあります。ストアは、アプリのデータの信頼できる唯一の情報源です。アプリケーションがどれほど大きくまたは複雑になっても、すべての状態が 1 か所に保存されるため、管理とデバッグが容易になります。

ストアを、アプリケーションが機能するために必要なすべての情報を含む巨大な JavaScript オブジェクトとして想像してください。ユーザーデータ、UI 状態、サーバー応答など、すべてがこのオブジェクトに保存されます。この一元的なアプローチは、個々のコンポーネント内でローカルに状態を管理する従来の方法とは対照的であり、状態の変化を追跡する際に不整合や困難が生じる可能性があります。

Redux のストアは不変です。つまり、一度設定された状態を直接変更することはできません。代わりに、変更が必要になるたびに新しい状態が作成されます。この不変性は、各状態の変更が意図的で追跡可能であることを保証するため、アプリケーションの予測可能性を維持するために非常に重要です。

2. アクション: 何が起こったかを説明する

Redux のアクションは、アプリケーション内のイベントまたは変更を記述するプレーンな JavaScript オブジェクトです。彼らは、アプリ内で何が起こったのかについての情報を伝えるメッセンジャーのようなものです。各アクションには、アクションの性質を定義する type プロパティと、オプションでアクションに関連する追加データを含むペイロード プロパティがあります。

たとえば、todo リスト アプリケーションでは、アクションは新しい todo 項目の追加、既存の項目の完了、または項目の削除を表す場合があります。これらのアクションにはそれぞれ、ADD_TODO、TOGGLE_TODO、DELETE_TODO などの一意のタイプがあり、Todo の ID やテキストなどの追加データが含まれる場合があります。

アクションはストアにディスパッチされ、そこでリデューサーによって処理されます (これについては次に説明します)。アプリケーションで何が起こったかを明確に定義することで、アクションはデータ変更の明確でわかりやすいフローを維持するのに役立ちます。

3. レデューサ: 状態がどのように変化するかを定義する

リデューサーは、アクションに応じてアプリケーションの状態がどのように変化するかを定義する Redux の純粋な関数です。これらは現在の状態とアクションを引数として受け取り、新しい状態を返します。 「純粋関数」という用語は、リデューサーの出力がその入力 (現在の状態とアクション) にのみ依存し、外部変数の変更や非同期操作の実行などの副作用を生成しないことを意味します。

Redux では、リデューサーが実際の状態の更新を担当します。アクションがディスパッチされると、Redux は現在の状態とアクションを適切なリデューサーに渡し、その後、新しい状態を計算して返します。このプロセスにより、予測可能かつ追跡可能な方法で状態が変化することが保証されます。

たとえば、ToDo リスト アプリケーションのリデューサーは次のようになります。

function todoReducer(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, action.payload];
    case 'TOGGLE_TODO':
      return state.map(todo =>
        todo.id === action.payload.id
          ? { ...todo, completed: !todo.completed }
          : todo
      );
    default:
      return state;
  }
}

この例では、todoReducer は ADD_TODO と TOGGLE_TODO の 2 種類のアクションを処理します。アクションの種類に応じて、新しい Todo 項目を状態に追加するか、既存の項目の完了ステータスを切り替えます。レデューサーは常に新しい状態オブジェクトを返し、元の状態が変更されないことを保証します。

Redux のセットアップと使用: 詳細なステップバイステップ ガイド

Redux の中核となる概念を説明したので、次はそれらが実際のアプリケーションでどのように組み合わされるかを見てみましょう。このセクションでは、単純な React アプリケーションで Redux をセットアップして使用するプロセスを順を追って説明します。

ステップ 1: Redux および関連パッケージをインストールする

Redux を使用する最初のステップは、必要なパッケージをインストールすることです。 Redux 自体はスタンドアロン ライブラリですが、React と一緒に使用する場合は、Redux を React コンポーネントと統合するためのバインディングを提供するパッケージ、react-redux もインストールする必要があります。

Redux と React-Redux をインストールするには、ターミナルを開き、プロジェクト ディレクトリで次のコマンドを実行します。

npm install redux react-redux

このコマンドは、Redux と React-redux の両方をインストールします。これは、React コンポーネントを Redux ストアに接続するために使用します。

ステップ 2: ストアを作成する

Redux がインストールされたら、次のステップはストアを作成することです。ストアはアプリケーションの状態を保持し、アクションをディスパッチしたり状態の変更をサブスクライブしたりするためのメソッドを提供します。

この例では、単純な ToDo リスト アプリケーションのストアを作成します。まず、状態の変更を処理するリデューサー関数を作成します。

import { createStore } from 'redux';

// This is our reducer function
function todoReducer(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, action.payload];
    case 'TOGGLE_TODO':
      return state.map(todo =>
        todo.id === action.payload.id
          ? { ...todo, completed: !todo.completed }
          : todo
      );
    default:
      return state;
  }
}

// Create the store
const store = createStore(todoReducer);

このコードでは、todoReducer 関数は 2 種類のアクションを処理します。新しい Todo 項目を追加する ADD_TODO と、項目の完了ステータスを切り替える TOGGLE_TODO です。 Redux の createStore 関数を使用してストアを作成し、引数として todoReducer を渡します。

ステップ 3: アクションとアクションクリエーターを定義する

アクションはアプリケーションで何が起こったかを記述するため、Redux では不可欠です。ただし、アクションをディスパッチするたびにアクション オブジェクトを手動で作成するのは面倒になる可能性があります。ここで、アクション クリエーターが登場します。アクション クリエーターは、アクション オブジェクトを返す関数です。

ToDo アイテムを追加するためのアクション クリエーターを定義しましょう:

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    payload: { id: Date.now(), text, completed: false }
  };
}

addTodo 関数はテキスト引数を受け取り、ADD_TODO タイプのアクション オブジェクトと、todo 項目データを含むペイロードを返します。このアクション クリエーターは、アクションをディスパッチするプロセスを簡素化し、コードをより読みやすく、保守しやすくします。

todo アイテムの完了ステータスを切り替えるために、toggleTodo などの他のアクション クリエーターを定義することもできます。

function toggleTodo(id) {
  return {
    type: 'TOGGLE_TODO',
    payload: { id }
  };
}

ステップ 4: 状態を更新するためにアクションをディスパッチする

ストアとアクションを配置したら、アクションをディスパッチして状態を更新できるようになりました。アクションのディスパッチは、アプリケーションで何かが起こったことを Redux に通知し、適切な Reducer をトリガーして状態を更新する方法です。

アクションをディスパッチして ToDo アイテムを追加したり切り替えたりする方法は次のとおりです。

store.dispatch(addTodo('Learn Redux'));
store.dispatch(addTodo('Build an app'));
store.dispatch(toggleTodo(1621234567890));

addTodo アクションをディスパッチすると、Redux は現在の状態とアクションを指定して todoReducer を呼び出し、Reducer は追加された todo 項目を含む新しい状態を返します。同様に、toggleTodo アクションをディスパッチすると、リデューサーは指定された Todo 項目の完了ステータスを更新します。

ステップ 5: 状態の変更にアクセスしてサブスクライブする

アプリケーションの現在の状態を読み取るには、ストアが提供する getState メソッドを使用できます。このメソッドは、Redux ストアに保存されている状態オブジェクト全体を返します:

console.log(store.getState());
// Output: [{ id: 1621234567890, text: 'Learn Redux', completed: true }, 
//          { id: 1621234567891, text: 'Build an app', completed: false }]

状態の読み取りに加えて、subscribe メソッドを使用して状態の変更をサブスクライブすることもできます。このメソッドを使用すると、状態が変化するたびにコールバック関数を実行できるため、UI を更新したり、状態の更新に応じて他の副作用を実行したりするのに役立ちます。

const unsubscribe = store.subscribe(() => {
  console.log('State updated:', store.getState());
});

状態変更のサブスクライブが完了したら、subscribe によって返された関数を呼び出すことでサブスクライブを解除できます。

unsubscribe();

ステップ 6: Redux を React コンポーネントに接続する

Redux を React と統合するには、React コンポーネントを Redux ストアに接続する必要があります。ここで、react-redux パッケージが活躍し、Provider、useSelector、および useDispatch ユーティリティを提供します。

まず、アプリケーション全体を Provider コンポーネントでラップし、Redux ストアを prop として渡します。これにより、React アプリのすべてのコンポーネントで Redux ストアが利用できるようになります:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './App';
import todoReducer from './reducers';

// Create the Redux store
const store = createStore(todoReducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

次に、useSelector フックと useDispatch フックを使用して、コンポーネントを Redux ストアに接続します。 useSelector を使用すると状態にアクセスでき、useDispatch を使用するとアクションをディスパッチできます:

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, toggleTodo } from './actions';

function TodoList() {
  const todos = useSelector(state => state);
  const dispatch = useDispatch();

  const handleAddTodo = (text) => {
    dispatch(addTodo(text));
  };

  const handleToggleTodo = (id) => {
    dispatch(toggleTodo(id));
  };

  return (
    <div>
      <button onClick={() => handleAddTodo('New Todo')}>Add Todo</button>
      <ul>
        {todos.map(todo => (
          <li
            key={todo.id}
            onClick={() => handleToggleTodo(todo.id)}
            style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
          >
            {todo.text}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoList;

In this example, the TodoList component displays a list of todo items, with the ability to add new items and toggle their completion status. The useSelector hook retrieves the state from the Redux store, while the useDispatch hook allows the component to dispatch actions.

By connecting your React components to Redux in this way, you can ensure that your application's state is managed consistently and predictably.

Best Practices and Common Pitfalls

While Redux is a powerful tool for managing state in complex applications, it also comes with its own set of best practices and potential pitfalls. Understanding these will help you avoid common mistakes and make the most of Redux in your projects.

Best Practices

  • Keep Your State Normalized: In large applications, it's essential to keep your state normalized, meaning that you avoid nesting data too deeply. Instead of storing entire objects within other objects, store only the references (e.g., IDs) and keep the actual objects in a separate, flat structure. This approach simplifies state updates and prevents unnecessary data duplication.
  • Use Action Creators: Action creators are functions that return action objects. They not only make your code more readable but also allow you to modify the structure of actions later without changing the code that dispatches them. Always use action creators instead of directly creating action objects in your components.
  • Use Immutable Update Patterns: Redux relies on immutability, meaning that state objects should never be modified directly. Instead, always return new objects when updating the state in reducers. You can use tools like the spread operator (...) or utility libraries like Immutable.js or Immer to help with this.
  • Keep Reducers Pure: Reducers should be pure functions, meaning that they should only depend on their arguments and not produce side effects, such as modifying external variables or making API calls. This purity ensures that your state changes are predictable and easy to test.
  • Split Your Reducers: As your application grows, so will your state. Instead of having one large reducer that handles everything, split your reducers into smaller, more manageable functions, each responsible for a specific part of the state. Redux provides a combineReducers function to help you merge these smaller reducers into a single root reducer.
  • Use Middleware for Side Effects: Redux is designed to be a synchronous state container, but many applications need to handle asynchronous actions, such as API calls. To manage these side effects, use middleware like redux-thunk or redux-saga, which allows you to handle asynchronous actions in a clean and maintainable way.

Common Pitfalls to Avoid

  • Overusing Redux: Not every piece of state needs to be stored in Redux. While Redux is great for managing application-wide state, it's overkill for local UI state that doesn't need to be shared across components. For example, the state of a dropdown menu or a modal window is better managed with React's built-in useState hook.
  • Mutating State Directly: One of the most common mistakes in Redux is directly mutating the state object in reducers. Doing so can lead to subtle bugs and make your application unpredictable. Always return a new state object instead of modifying the existing one.
  • Putting Everything in One Reducer: While it's possible to manage your entire application's state with a single reducer, doing so will quickly become unmanageable as your application grows. Instead, break down your state into smaller pieces and create a reducer for each piece. Use combineReducers to merge them into a single root reducer.
  • Ignoring the Redux DevTools: Redux DevTools is an invaluable tool for debugging and understanding how your state changes over time. It allows you to inspect every action that is dispatched, view the current state, and even "time travel" by replaying actions. Make sure to integrate Redux DevTools into your development environment.
  • Not Handling Side Effects Properly: Redux is designed to be a synchronous state container, but most applications need to deal with asynchronous actions, such as API calls. If you handle these side effects within reducers or actions, you break the purity of your functions and make your code harder to test and maintain. Instead, use middleware like redux-thunk or redux-saga to manage side effects.

Conclusion and Next Steps

In this comprehensive guide, we've covered the fundamentals of Redux, from its core concepts to setting up and using it in a simple React application. Redux is a powerful tool for managing state in complex applications, but it also comes with its own learning curve and best practices.

ストア、アクション、およびリデューサーを理解することで、アプリケーションの状態を制御し、アプリケーションが予測どおりに一貫して動作することを保証できます。提供されているステップバイステップのガイドを使用すると、独自のプロジェクトで Redux をセットアップし、プロのように状態管理を開始できるようになります。

しかし、Redux は多くの高度な機能とユースケースを備えた広大なトピックです。理解を深めるために、次のことを検討してください:

  • ミドルウェア: redux-thunk や redux-saga などのミドルウェアを使用して非同期アクションと副作用を処理する方法を学びます。
  • Redux Toolkit: Redux Toolkit を使用して Redux 開発を簡素化します。Redux Toolkit は、Redux の操作をより簡単かつ効率的にするためのツールとベスト プラクティスのセットです。
  • Redux アプリケーションのテスト: リデューサー、アクション、および接続されたコンポーネントの単体テストを作成する方法を学びます。
  • 高度なパターン: 複雑な状態形状の処理、パフォーマンスの最適化、Redux と他のライブラリの統合など、高度な Redux パターンを発見します。
  • コミュニティとリソース: Redux コミュニティに参加し、公式ドキュメントを読み、オンライン チュートリアルやコースを探索して学習を続けてください。

Redux をマスターするには時間と練習が必要であることを覚えておいてください。やればやるほど快適になります。実験を続け、学び続けてください。

以上がRedux について: 初心者向けの総合ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。