Redux Tutorialをやろうとしたのですが、ちょっとレベルが高く理解しにくと思ったので最小限のカウントアプリを作りながらReduxについて自分なりにまとめてみました。
用語の整理
redux
アプリケーションの状態を管理するためのオープンソースのJavaScriptライブラリ。
react-redux
reduxとreactをつないでくれる便利なやつ。
store
stateの値を保持するオブジェクトのこと。
reducer
actionのtypeをトリガーにしてstateを返す関数のこと。
action
reducerにstateがどのように変わるのかを伝えるオブジェクトのこと。 必ず、typeというkeyを持つ。
Provider
storeを参照できるようにしてくれるやつ
connect
ReactコンポーネントをRedux storeに繋いでくれるやつ
試す
以下の環境で試しました。
node v12.18.0 react 16.13.1 redux 4.0.5 react-redux 7.2.0
プロジェクトを作成する
create-react-appで作っていきます。
$ create-react-app my-app
create-react-app が入っていない場合は、インストールが必要です。
$ yarn add global create-react-app
起動する
$ yarn start
スタート画面が表示されればOKです。
パッケージを追加する
$ yarn add redux react-redux
適当にカウントアプリのUIを作る
import React from 'react'; import logo from './logo.svg'; import './App.css'; const App = () => { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1>0</h1> <button>+</button> <button>-</button> </header> </div> ); } export default App;
actionを作る
$ mkdir src/actions $ mkdir touch src/actions/index.js
const INCREMENT = "INCREMENT" const DECREMENT = "DECREMENT" export const increment = () => ({ type: INCREMENT }) export const decrement = () => ({ type: DECREMENT })
reducerを作る
$ mkdir src/reducers $ touch src/reducers/index.js
import { INCREMENT, DECREMENT } from "../actions" const initializeCount = { count: 0 }; const Counter = (state = initializeCount, action) => { switch(action.type){ case INCREMENT: return { count: state.count + 1} case DECREMENT: return { count: state.count - 1} default: return state } } export default Counter
storeを作る
//以下を追加 import { createStore } from 'redux' import Counter from "../src/reducers" const store = createStore(Counter, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
createStoreの第二引数にReduxのデバックツールを使う設定を追加しています。
良い感じにチェックできます。
ReactとReduxを繋ぐ
ProviderでAppを囲む
・ import { Provider } from 'react-redux' ・ ・ ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
connectを使って繋ぐ
・ ・ import { increment, decrement } from "../src/actions" import { connect } from "react-redux" const App = props => { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1>{props.count}</h1> <button onClick={props.increment}>+</button> <button onClick={props.decrement}>-</button> </header> </div> ); } const mapStateToProps = (state) => { return { count: state.count } } const mapDispatchToProps = { increment, decrement } export default connect( mapStateToProps, mapDispatchToProps )(App)
動作確認
動作を確認することができました。