React+Reduxを触ってみたいんだけどサンプルコードがイマイチ分かりにくいし、もっと単純なサンプルで動かしてみたい!という人用に、数値をインクリメントするだけのなるべく単純化したサンプルを作成し、おおまかな説明を付けました。
なお本格的に触る場合は、公式ドキュメントを参照されることをお薦めします。
使うもの
- Node.js v9.11.1
- npm v5.8.0
- react v16.3.1
- redux v3.7.2
- webpack v4.5.0
基本的なReduxの流れ
準備
まずは適宜作業スペースを用意。
mkdir react-redux-sample
cd react-redux-sample
npm init --yes
必要なパッケージを入れます。webpackを用いるのでその辺りも入れます。
npm install react react-dom react-redux redux
npm install --save-dev webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env @babel/preset-react
ソース
index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
確認用のhtmlです。bundle.js
はwebpackで生成するjsです。
index.jsx
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
const reducer = function (state = {count: 1}, action) {
switch (action.type) {
case 'INCREMENT':
return {
count: state.count+1
};
default:
return state;
}
};
const store = createStore(reducer);
import App from './App.jsx';
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Reactのrender処理と、Reduxのstoreを準備しています。
- reducerはReduxにおいて、actionを受け取ってstateを更新する役割を担っています。
- 今回はINCREMENTアクションを受けた時、countを+1しています。
- reducerをcreateStore()に渡すことでRedux storeを生成します。
- ProviderはReactとReduxを繋ぐ仕組みの一環です。
App.jsx
import React from 'react';
import { connect } from 'react-redux';
function App({ count, onIncrementClick }) {
return (
<div>
<span>{count}</span>
<button onClick={() => { onIncrementClick(); }}>
inc
</button>
</div>
);
};
export default connect(
state => {
return { count: state.count };
},
dispatch => {
return {
onIncrementClick: () => {
dispatch({ type: 'INCREMENT' });
}
};
}
)(App);
Reactコンポーネントです。
- connect()はreact-reduxが提供する、ReactコンポーネントとRedux storeを繋ぐ処理で、ReduxからReactコンポーネントに渡すstateやdispatchをそれぞれ設定します。
-
{ type: 'INCREMENT' }
はactionであり、dispatch()に渡すことでreducerに伝わります。
動作確認
webpackを設定します。
webpack.config.js
var path = require('path');
module.exports = {
mode: 'development',
entry: './index.jsx',
output: {
path: path.resolve('dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
]
}
};
以下のコマンドでwebpack-dev-serverを起動。
npx webpack-dev-server --progress --hot
http://localhost:8080/webpack-dev-server/index.html
にアクセスすると動作が確認できます。