tag:crieit.net,2005:https://crieit.net/tags/Redux/feed 「Redux」の記事 - Crieit Crieitでタグ「Redux」に投稿された最近の記事 2018-10-31T18:32:18+09:00 https://crieit.net/tags/Redux/feed tag:crieit.net,2005:PublicArticle/14296 2016-08-22T23:02:13+09:00 2018-10-31T18:32:18+09:00 https://crieit.net/posts/React-Redux ReactにReduxを組み合わせると何が楽なのか <p>React + Reduxを使うとどうメリットがあるかというと、色々とあるとは思う。<br /> ただ、どう楽になるのかというのに焦点をおいてみる。</p> <h3 id="Reactのみの例"><a href="#React%E3%81%AE%E3%81%BF%E3%81%AE%E4%BE%8B">Reactのみの例</a></h3> <p>下記のようなコンポーネント構成のアプリケーションを作成するとする。</p> <ul> <li>コンテナ : App <ul> <li>ヘッダ : Header</li> <li>ログインボタン : Login(ログイン時はユーザー名表示)</li> <li>コンテンツ : Contents</li> </ul></li> </ul> <p>Reactのみだと関連箇所は下記のようなjsxになるだろう。</p> <p>App</p> <pre><code class="javascript"><div> <Header user={this.state.user} onLogined={this.onLogined} /> <Contents user={this.state.user} contents={this.state.contents} /> </div> </code></pre> <p>Header</p> <pre><code class="javascript"><div> <Login user={this.props.user} onLogined={this.props.onLogined} /> </div> </code></pre> <p>Login</p> <p>handleLoginでサーバーへのログインリクエストを行い成功したらthis.props.onLoginedを呼び出す。</p> <pre><code class="javascript"><div> <button onClick={this.handleLogin}>ログイン</button> </div> </code></pre> <p>共通で使用される値は一番上の階層で扱うのが望ましいので、<br /> 見ての通りuserとonLoginedをひたすらプロパティで引き継ぎまくる事になってしまう。<br /> Reactの良さを理解してもこのあたりでうんざりしてくる。</p> <h3 id="React + Reduxにすると"><a href="#React+%2B+Redux%E3%81%AB%E3%81%99%E3%82%8B%E3%81%A8">React + Reduxにすると</a></h3> <p>プロパティでの指定が不要になる。<br /> 簡単なログアウトボタンの例は下記の様になる。<br /> (actionやreducer等の細かい部分の解説は省く)</p> <pre><code class="javascript">import React from 'react'; import { connect } from 'react-redux'; import request from 'superagent'; import { setUser } from '../../actions/main'; function mapDispatchToProps(dispatch) { return { handleLogin: (user) => dispatch(setUser(user)), }; } class Logout extends React.Component { handleSubmit(e) { request.post('/logout') .end((err, res) => { if (!err) { this.props.handleLogin(null); } }); } render() { return ( <button onClick={this.handleSubmit}>ログアウト</button> ); } } export default connect((state) => state, mapDispatchToProps)(Logout); </code></pre> <p>上記のようにコールバックのプロパティもその場で決められる。<br /> また、下記のように、ヘッダー側のユーザー情報表示もuserを引き継がなくても取得できる。<br /> (connectにより勝手にpropsに入っている)</p> <pre><code class="javascript">import React from 'react'; import { connect } from 'react-redux'; import Login from './login'; import Logout from './logout'; import { setUser } from '../../actions/main'; class Header extends React.Component { renderUser() { if (this.props.user == null) { return <Login />; } return ( <div> こんにちは{this.props.user.name}さん <Logout /> </div> ); } render() { const user = this.renderUser(); return ( <div> <h1>タイトル</h1> {user} </div> ); } } export default connect((state) => state)(Header); </code></pre> <h3 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h3> <p>どんどん細かくコンポーネントするのがよい、ということのはずだがそれをデメリットに変えてしまう自己矛盾したプロパティの仕組み。<br /> Reduxによってそれが解消され使い勝手の良い物になる。<br /> 極小アプリケーションでない限りはほぼ必須であると思われる。</p> だら@Crieit開発者