質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

2823閲覧

react+reduxで作成しているソースファイルの肥大化をなんとかしたい

kujira13

総合スコア7

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2017/02/16 04:20

###前提・実現したいこと
react+reduxで開発しているclassの肥大化をなんとかしたい

###発生している問題・エラーメッセージ
es6(babel)+react+reduxの環境で開発を実施しています。
現在の方針はトップのコンテナーのclassに全ての処理を実装し、それを実際に使用する子コンポーネントまでバケツリレーすることで処理を実施しています、
作業が進むにつれ、classの肥大化が目立ってきました。
肥大化を防ぐ良い案はないでしょうか。

###該当のソースコード

javascript

1import React from 'react'; 2 3import Header from './Header'; 4import Main from './Main'; 5import Footer from './Footer'; 6 7class AdminContainer extends React.Component { 8 constructor(props) { 9 super(props); 10 11 this.method1 = this.method1.bind(this); 12 this.method2 = this.method2.bind(this); 13 this.method3 = this.method3.bind(this); 14 } 15 16 /* 下位に渡すmethodが増え、ファイルがどんどん大きくなる */ 17 method1(){ ...省略... } 18 method2(){ ...省略... } 19 method3(){ ...省略... } 20 21 render() { 22 <div> 23 <Header /> 24 <Main 25 Method1={this.Method1()} 26 Method2={this.Method2()} 27 Method3={this.Method2()} 28 /> 29 <Footer /> 30 </div> 31 ); 32 } 33} 34 35###試したこと 36classに対し、別ファイルにてprototypeによる実装を行いましたが、うまくいかず・・・ 37何か他にいい案ありましたら、お願いいたします。 38 39import AdminContainer from './AdminContainer'; 40 41AdminContaner.prototype.method4 = () => { 42 ...省略... 43}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Reduxも使っているのであれば、react-reduxも使ってみてください。そしてUsage with Reactで書き方を学んでみてください。それだけで、肥大化は防げるはずです。

以下、Reduxの公式マニュアルが推奨している方法です(たぶん)。かといって、必ずこうしろと言うわけではありません。

始めに、コンポーネントを二つの種類に分けます。

  • 表現部品 Presentational Components

どのような見た目にするのかを書くコンポーネントです。divやspanとかではない意味のあるHTMLのタグが実際に使われるのもこのコンポーネントです。

  • 容器部品 Container Components

どのように動くのかを書くコンポーネントです。いわゆる振る舞いやロジックをここに書きます。

renderするときは、これが入れ子のように作ります。サンプルを作ったので見てましょう。わかりやすいようにPresentational Componentsは終わりにPを、Container Componentsは終わりにCを付けた名前にしています(そういう命名規則にすべきとかはありません)。
※ HTMLで1ファイルになるようにしていますが、実際は分割して作ることになるでしょう。
※ Presentational Componentsは状態を持たないため、stateless functional componentsとして作成できます。つまり、一つの関数としてくれると言うことで、これはrender()しかないReact.Componentと同じです。

HTML

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width"> 6 <title>React Redux Sample</title> 7</head> 8<body> 9 <div id="main"></div> 10 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js"></script> 11 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script> 12 <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js"></script> 13 <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.2/react-redux.min.js"></script> 14 <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.23.1/babel.min.js"></script> 15 <script type="text/babel"> 16const InputTextP = () => ( 17 <textarea name="text"> 18 </textarea> 19); 20const SubmitButtonP = () => ( 21 <button type="submit"> 22 出力 23 </button> 24); 25const InputP = ({onSubmit}) => ( 26 <form onSubmit={onSubmit}> 27 <InputTextP /> 28 <br /> 29 <SubmitButtonP /> 30 </form> 31); 32const InputC = ReactRedux.connect( 33 (state, ownProps) => ({}), 34 (dispatch, ownProps) => ({ 35 onSubmit: (e) => { 36 e.preventDefault(); 37 dispatch(submit(e.currentTarget.text.value)); 38 } 39 }), 40)(InputP); 41const MessageP = ({text}) => ( 42 <pre> 43 {text} 44 </pre> 45); 46const OutputC = ReactRedux.connect( 47 (state, ownProps) => ({ 48 text: state.text 49 }) 50)(MessageP); 51const MainP = () => ( 52 <div> 53 <InputC /> 54 <OutputC /> 55 </div> 56); 57 58const SUBMIT = 'SUBMIT'; 59const submit = (text) => ({ 60 type: SUBMIT, 61 payload: {text} 62}); 63const initialState = { 64 text: '' 65}; 66const reducer = (state = initialState, action) => { 67 switch (action.type) { 68 case SUBMIT: 69 return Object.assign({}, state, { 70 text: action.payload.text 71 }) 72 default: 73 return state 74 } 75}; 76const store = Redux.createStore(reducer) 77 78ReactDOM.render( 79 <ReactRedux.Provider store={store}> 80 <MainP /> 81 </ReactRedux.Provider>, 82 document.getElementById('main') 83); 84 </script> 85</body> 86</html>

階層構造は下記のようになっています。

MainP <div> ├InputC │└InputP <form> │ ├InputTextP <textarea> │ └SubmitButtonP <button> └OutputC └MessageP <pre>

さらにPresentational Componentsの中にContainer Componentsを入れてもかまいません。react-reduxが提供するProviderにstoreを渡すことで、自動的にコンポーネントでは同じstoreを受け取って、それに対するstateやdispatchが使えるようになっています。

Container Componentsで振る舞いを全て書くことになるため、ここが肥大化しそうと思うかも知れませんが、細かくコンポーネントに分割していけば、わかれて記載可能です。また、モジュールベースで作っていれば、別のページや場所での再利用も簡単にできるでしょう。

さわりだけですが、なんとなく掴めたでしょうか?ReduxはFluxの一種(厳密に違うが)であり、各コンポーネントでstateを持つことを防ぐものでした。かといってトップから全て渡していく必要があるというものでもありません。コンポーネント単位で必要な情報だけ取得していくと再利用性が高い物ができるかと思います。

投稿2017/02/18 07:32

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kujira13

2017/02/27 02:34

意味が理解できるまで時間がかかってしまい、結果お礼が遅くなってしまい申し訳ありません。 いただいた回答のおかげで無事解決いたしました。 今回、メインとなるMainPを作り、その下にHeaderC、ContentsC、FooterCを作り、その下に、それぞれPをぶら下げました。 また、一つだったstateを3つのファイルに分け、react-rudexのmapStateToPropsで取得することで良い感じで分割できました。 ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問