2016-05-04 13 views
1

Reactでかなり複雑なチャートコンポーネントを構築することを考えています。言うまでもなく、そのようなコンポーネントには、何とかして管理する必要のある多数の状態があります。内部の独立したReduxストアを持つリジューム可能なコンポーネント

Reduxはこれに最適だと思われますが、プロバイダのトップレベルのコンテナをカスタムストアでラップすると、コンポーネントの内部のreduxストアはグローバルなアプリケーションの状態に干渉しませんより大きなReact/Reduxアプリに含まれていますか?

import React, { Component } from 'react'; 
import { createStore } from 'redux'; 
import { Provider } from 'react-redux'; 
import internalReducer from './reducer'; 

export default class MyReduxComponent extends Component { 

    render() { 
     const store = createStore(internalReducer, this.props.initialState); 
     return <Provider store={store}> 
      <Chart /> 
     </Provider> 
    } 

} 

答えて

1

あなただけ使用していない理由は、コンポーネントの状態が反応しますか? Reduxは、アプリケーション全体で複数のコンポーネントがアクセスできる必要がある状態で使用するためのものです。特定のコンポーネントの子孫によって使用されることだけを意味する状態を管理している場合、コンポーネント状態を使用することもできます。その場合、Reduxは必要ありません。あなたのコンポーネントは、そうした方法ではるかに再利用可能になり、追加の依存関係に依存しません。

+1

ええ、しかし、コンポーネントは、お互いの状態についてすべて知る必要がある14の異なるサブコンポーネントで構成されていると考えてください。それは面倒な速さになるでしょう。 – hampusohlsson

+1

主要なトップレベルのチャートコンポーネントは、その子孫間で共有する必要がある状態を管理します。それらの子孫は小道具を介してその状態にアクセスしたり変更したりすることができます。子孫コンポーネントは共有状態を保持しません。このアプローチは、何らかの組み込みReduxを使用しようとするよりも面倒ではありませんし、意図された用途に沿ったものです。 –

+0

あなたは正しいと思います。誰かがこの質問に遭遇した場合、私はプロトタイプで回答を作成しました。 – hampusohlsson

1

あなたのコンポーネントは、独自の内部Reduxの店舗を持っているのではなく、減速機が知っている、それは簡単に既存のReduxのアプリと統合することができ、独自の減速+アクション/アクションクリエイターを持つべきではありません。

import { chartReducer, chartActionCreators } from 'your-chart' 

combineReducers({ 
    ...global.stuff, 
    chartReducer 
}) 

store.dispatch(chartActionCreators.action()) 

-- 

import Chart from 'your-chart' 

export default() => 
    <div> 
    <Chart /> 
    </div> 

あなたのライブラリのユーザーは、何らかのアクションを明示的に使用する必要はありません。リデューサーだけで十分である必要があります。そのため、チャートの状態にはアプリ内のどこでもアクセスできます。

さらに、何らかの方法でアクション呼び出しを増やす必要がある場合は、ミドルウェアを書くことができます。

http://redux.js.org/docs/advanced/Middleware.html

+0

のようになります。私もそのことを考えたが、その後、私のコンポーネントが着る人のために役に立ちません還元を使わない? – hampusohlsson

+1

それは必ずしも真実ではありません...それは実際にそれをどのように実装するかによって異なります。もしあなたがまだ利用可能でないなら、自分のreduxストアにフォールバックすることができます。あなたは 'this.state'にフォールバックすることができます。複数のバージョンのチャートをエクスポートできます。ここにはいくつかの可能性がありますが、既に1つの還元です。入れ子にされたものは良い考えではありません。なぜなら、 'connect'は異なるプロバイダを見ているからです。 – azium

+0

また、 'redux'はフラックスの標準になっています。それはFacebookの適切なgithubアカウントの一部です。 'redux-chart'ライブラリを作ることは非常に高く評価されています(既存のものがない場合) – azium

1

私はこの問題を解決するためには、childContextTypessetStateを最上位コンポーネントに使用して、非常に良い方法を見つけたと思います。これにより、深度のあるサブコンポーネントは必要なコンテキストアクションを「インポート」できます。 (複数のネストされたコンポーネントを介して小道具としてコールバックを渡す必要性を排除します)。

Example on JSBin

トップコンポーネントは、この

export default class ReusableComponent extends Component { 

    // Define the public API interface to child components 
    static childContextTypes = { 
    // expose component state store 
    store: PropTypes.object, 
    // actions 
    setFoo: PropTypes.func, 
    setBar: PropTypes.func 
    }; 

    // Set initial state, can be overriden by props 
    constructor(props) { 
    super(props) 
    this.state = { 
     foo: 'My Foo', 
     ...props 
    } 
    } 

    // Define methods for public API 
    getChildContext() { 
    return { 
     store: this.state, 
     setFoo: this.setFoo.bind(this), 
     setBar: this.setBar.bind(this) 
    }; 
    } 

    // Reducer for action setFoo 
    setFoo(foo) { 
    this.setState({ foo }) 
    } 

    // Just render components, no need for passing props 
    render() { 
    return <div> 
     <UpdateFooComponent /> 
     </div> 
    } 

} 

と子コンポーネント

class UpdateFooComponent extends Component { 

    // 'import' the store and actions you need from top component 
    static contextTypes = { 
    store: PropTypes.object, 
    setFoo: PropTypes.func 
    }; 

    clickHandler(e) { 
    this.context.setFoo('Hello from subcomponent'); 
    } 

    render() { 
    const { foo } = this.context.store; 
    return <div> 
     <button onClick={::this.clickHandler}>Update foo</button> 
     <p><strong>foo:</strong> {foo}</p> 
    </div> 
    } 

} 
+0

それは確かにうまくいくはずです。コンテキストはグローバル変数に似ていますので、可能であれば避けてください。たとえば、この場合、ReusableComponentに「ストア」コンテキストを定義しています。このコンポーネントを使用している誰もがreact-reduxを使用している場合、react-reduxのProviderコンポーネントも 'store'コンテキスト。また、おそらくあなたが知っているように、コンテキストは実験的なものとみなされているため、APIが変更される可能性があります。 –

+0

右...うーん。だから、最善の方法は、子どもたちに渡すだけでなく、それを使わないコンポーネントに小道具を送ることを意味していても、すべてのものを小道具として渡すことです。 – hampusohlsson

+1

これはおそらくデフォルトの選択です。コンポーネントを介して小道具を渡すことが大きな混乱になる場合は、コンテキストの利便性とその欠点との間のトレードオフを考慮する必要があります。しかし、ほとんどの場合、小道具で見つかるはずのエレガントなソリューションがあり、コンポーネントを通じたデータの流れを追跡するのが簡単になります。このトピックに関するいくつかの「コンテキスト」(ティー・ヒー)については、react-reduxでのコンテキストの使用に関するDan Abramov(Reduxの作成者)によるこの回答をチェックしてください:http://stackoverflow.com/questions/36428355/react-コンセプトの問題 –

関連する問題