Redux は状態管理に特化しており、React とは切り離されています。また、Redux は Angular とも組み合わせて使用することができます。この記事では、実例を交えながら Redux の使用方法を説明し、Redux をより理解しやすくします。
Redux の基本的な概念を理解している場合、Redux を使用してみましょう。Redux は状態管理に特化しており、React とは切り離されています。また、Redux は Angular とも組み合わせて使用することができます。この記事では、React アプリケーションで Redux を使用してアプリケーションを開発する方法を試みますが、react-redux は使用しません。これにより、Redux のデータフローを理解するのに役立ちます。
完全なコードは Github で確認できます:https://github.com/YanYuanFE/redux-app
// リポジトリをクローン
git clone https://github.com/YanYuanFE/redux-app.git
cd redux-app
// ブランチをチェックアウト
git checkout part-1
// インストール
npm install
// 開始
npm start
開始#
まず、React アプリケーションを初期化します。作成するためには、事前にインストールする必要があります。コマンドラインを開き、次のコマンドを入力します:
npm i create-react-app -g
これにより、グローバルにインストールされます。次に、開発の準備ができたディレクトリに移動し、コマンドラインを開き、次のコマンドを入力します:
create-react-app redux-app
完了するまで待ちます。次に、
cd redux-app
と入力し、npm start を実行します。React アプリケーションが自動的に起動し、ブラウザが開きます。
次に、Redux をインストールする必要があります。コマンドラインで次のコマンドを入力します:
npm i redux --save
次に、Redux の部分を書いていきます。
Redux#
アプリケーションが比較的シンプルなので、reducer の部分を直接書くことができます。src ディレクトリの下に reducers ディレクトリを作成し、index.js を作成します。reducer では、アクションを処理して新しい状態を返すことによって、アクションを処理します。このアプリケーションでは、カウンターのアクションは加算と減算の 2 種類があります。それぞれを 'INCREMENT' と 'DECREMENT' と定義し、カウンターを増やすアクションがトリガーされた場合は state + 1、カウンターを減らすアクションがトリガーされた場合は state - 1、それ以外の場合は元の state を返します。また、reducer 全体を export default して他の部分で使用できるようにします。以下はコードです:
export default (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
reducer の作成が完了したら、次は store を作成し、アプリケーション全体に注入する必要があります。ここでは、src ディレクトリの index.js を変更し、redux から import して、reducer を使用して createStore メソッドを呼び出してアプリケーションの状態 store を生成し、store を props 経由でアプリケーションのルートコンポーネント App に渡す必要があります。同時に、元のレンダリングロジックを render メソッドにカプセル化し、手動で呼び出す必要があります。また、store が変更された場合、アプリケーションは自動的に再レンダリングされません。store.subscribe (render) メソッドを使用して、store の変更を手動で購読する必要があります。store.subscribe (render); は、store が変更されたときに render メソッドを呼び出し、アプリケーション全体を再レンダリングすることを意味します。
ReactDOM.render(<App store={store}/>, document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { createStore } from 'redux';
import registerServiceWorker from './registerServiceWorker';
import counter from './reducers';
const store = createStore(counter);
const render = () => ReactDOM.render(<App store={store}/>, document.getElementById('root'));
render();
store.subscribe(render);
registerServiceWorker();
コンポーネントの作成#
props を介して受け取った store を使用して、APP コンポーネント内でデータを取得し、アクションをトリガーする必要があります。APP コンポーネントでは、コンポーネントのロジックを分離するために、カウンターに関連する実装を別のコンポーネントに分離します。APP コンポーネントは、データとイベントを props を介してカウンターコンポーネントに渡す役割を担います。
src ディレクトリの下に components ディレクトリを作成し、Counter.js を作成します。以下はカウンターのコードです:
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.incrementAsync = this.incrementAsync.bind(this);
this.incrementIfOdd = this.incrementIfOdd.bind(this);
}
render() {
const { value, onIncrement, onDecrement } = this.props;
return (
<p>
Clicked: {value} times
{' '}
<button onClick={onIncrement}>
+
</button>
{' '}
<button onClick={onDecrement}>
-
</button>
</p>
)
}
}
export default Counter;
Counter コンポーネントでは、props を介して親コンポーネントから渡された value と増加、減少のメソッドを受け取ります。value はビューに表示されるカウンターの値にバインドされ、増加、減少のボタンはそれぞれ親コンポーネントから渡されたメソッドをボタンにバインドします。
次に、src ディレクトリの App.js でカウンターコンポーネントをインポートし、render メソッドで使用します。
import React, { Component } from 'react';
import Counter from './components/Counter';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
const { store } = this.props;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
/>
</div>
);
}
}
export default App;
APP コンポーネントでは、props 内の store を使用するために ES6 のオブジェクト分割構文を使用し、render メソッド内で Counter コンポーネントをレンダリングします。同時に、約束された props を Counter コンポーネントに渡し、カウンターの値 value は store.getState () を使用して取得し、増加のメソッド onIncrement は store.dispatch を呼び出してアクションを発行し、アクションには増加を表す 'type' が渡されます。同様に、減少のメソッド onDecrement には 'actionType' として 'DECREMENT' が渡されます。
ここまでで、カウンターアプリケーションの開発は完了です。
npm start
アプリケーションを起動し、ブラウザを開くと、最終的な結果は以下のようになります:
+、- ボタンをクリックすると、数字が増減し、数字はリアルタイムで更新されます。
最後に#
Redux を使用してカウンターアプリケーションを実装しました。Redux のフローを整理してみてください。まず、Redux のコアは store、action、reducer です。store はグローバルなアプリケーションに公開され、store を使用して state を取得し、action をトリガーし、state の変更を購読することができます。state のデータを変更するには、必ずアクションをトリガーする必要があります。アクションはいくつかのインタラクションやイベントを介してトリガーすることができ、reducer はアクションを処理し、新しい state を返します。state が変更されると、store の subscribe メソッドがトリガーされ、ビューを更新するために使用できます。React を使用してアプリケーションを開発している場合、アプリケーションが複雑になると、単に Redux を使用するだけでは煩雑になる可能性があります。必要なコンポーネントに store を props として渡すために、store を一つずつ渡す必要があります。このような問題を解決するために、react-redux が登場し、簡単な方法でグローバルな状態にアクセスできるようになりました。それでは、楽しみにしてください。