2017-06-06 4 views
0

Q:特定の再利用可能なコンポーネントからパブリックメソッドにアクセスするインターフェイスを提供する方法はありますか?メソッドへのReactコンポーネントインターフェイス

シナリオ:Tabsコンポーネントをビルドしているとします。

<App> 
    <Tabs /> 
    <button id="previous">Previous</button> 
    <button id="next">Next</button> 
</App> 

あなたが前または次のタブのペインに移動、Tabsコンポーネントと対話すべき二つのボタンがある見ることができるように:それはAppと呼ばれ、親コンポーネント内に位置しています。

export default class Tabs extends React.Component { 
    next() {} 
    previous() {} 
} 

Q:

私の実装はTabsコンポーネント内next()previous()方法を維持することにあるどのように私はAppコンポーネント内のこれらのボタンにnext()previous()方法をバインドすることができますか? Tabsコンポーネントで公開されているインタフェースを作成することはできますか? とは何ですか?はきれいですそうする方法はありますか?

編集1:...

編集2Tabsは "再利用可能" なコンポーネントです。多くのアプリケーションは内部でそれをレンダリングできます。

答えて

1

あなたのボタンがあなたのTabsコンポーネントの外にあることは他の人からもわかりません。

コードサンプルの表示方法は、AppコンポーネントがTabsコンポーネントである必要があります。TabsコンポーネントがTabsViewのようなものを代表すると仮定します。

app.js

import Tabs from './components/tabs'; 

<App> 
    <Tabs/> 
</App> 

tabs.js

class TabsView extends Component { 
    constructor(props){ 
    super(props); 
    } 
    render(){ 
    return(
     <span>{this.props.currentTab}</span> 
    ); 
    } 
} 

class Tabs extends Component { 
    constructor(props){ 
    super(props); 
    this.state = { 
     currentTab: 0 
    } 
    } 
    handleOnClickPrev(){ 
    this.setState({currentTab: currentTab--}); 
    } 
    handleOnClickNext(){ 
    this.setState({currentTab: currentTab++}); 
    } 

    render(){ 
    return(
     <div> 
     <TabsView currentTab={this.state.currentTab}/> 
     <button id="prev" onClick={handleOnClickPrev.bind(this)}>-</button> 
     <button id="next" onClick={handleOnClickNext.bind(this)}>+</button> 
     </div> 
    ); 
    } 
} 

export default Tabs; 

この方法で、その中にあなたのコンポーネントの人生のすべての機能。 Tabsコンポーネントには、必要なすべての情報が含まれています。それぞれのTabsコンポーネントには独自の状態とタブがあります。現在のタブ状態がAppから来て、他の場所でこの同じcurrentTabをレンダリングできるようにするには、Appコンポーネントから小道具として渡すことができます。

app.js

<App> 
    <Tabs currentTab={this.state.currentTab} handlePrev={} handleNext={}/> 
</App> 

tabs.js

class Tabs extends Component { 
    constructor(props){ 
    super(props); 
    } 

    render(){ 
    return(
     <div> 
     <TabsView currentTab={this.props.currentTab}/> 
     <button id="prev" onClick={this.props.handlePrev}>-</button> 
     <button id="next" onClick={this.props.handleNext}>+</button> 
     </div> 
    ); 
    } 
} 

export default Tabs; 

あなたが他の場所でボタン特定の場所にタブを表示するために探していない場合は、使用することができますTabsViewコンポーネントは、Tabsコンポーネントに渡す同じ小道具を使用しています。

app.js

<App> 
    <Tabs currentTab={this.state.currentTab} handlePrev={} handleNext={}/> 
    <TabsView currentTab={this.state.currentTab} /> 
</App> 

あなたがコンポーネント自体よりも、別の場所でのライブのコンポーネントのためにあなたのコントロールを持つのは本当に暴勇している場合は、私は両方のTabsViewまで同じ小道具を渡すことを示唆しているとボタン。

app.js

handlePrev() { 
    this.setState({ currentTab: this.state.currentTab - 1 }) 
} 
handleNext(){ 
    ... 
} 
render(){ 
    return (
    <App> 
     <TabsView currentTab={this.state.currentTab} /> 
     <button id="prev" onClick={this.handlePrev.bind(this)}>-</button> 
     <button id="next" onClick={this.handleNext.bind(this)}>+</button> 
    </App> 
) 
} 

私はあなたがこの時点でReduxのか、他の状態のライブラリを導入することは理にかなっているとは思いません。あなたのタブコンポーネントのためだけにグローバル状態を管理することは大変です。

+1

いくつかの考えの後で、このアプローチはより「反応的」である。ありがとうございました!私はこの解決策に終わった。 <3 – Richard

1

ボタンがTabコンポーネントの要素に作用する場合、これらのボタンはこのコンポーネントの内側にある必要があります。 ButtononPress小道具を使用して、コンポーネントのstateを簡単に変更することができます。

あなたはまだ(私はそののための明確な理由が表示されていない場合でも)コンポーネントの外側で、あなたのボタンを維持したい場合、あなたは全体の「グローバル」状態を維持するためにReduxのような店を使用して検討すべきですあなたのコンポーネント。

+0

解決策としてグローバルなアプローチを導入すると、Reduxがすべてを混乱させるようです。 私はそれがスケーラブルであることを意味しますか?私は 'Tabs'アクションを' Tabs'コンテキストの中に保たなければならないのですか?これを処理するための何らかのインターフェースを提供していますか? – Richard

+1

Reduxを正しく使用するだけです。たとえば、 'GO_TO_NEXT_TAB'や' GO_TO_PREVIOUS_TAB'のようなアクションを持つ 'NavigationReducer'があります。しかし、もう一度、このユースケースでは、タブコンポーネントにボタンが埋め込まれている必要があります。 – c4k

2

あなたはrefは、親コンポーネント

class Root extends Component { 

    render() { 
    return (
    <App> 
     <Tabs ref={ref => this.tabs = ref} /> 
     <button id="previous" onClick={() => this.tabs.prev()}>Previous</button> 
     <button id="next" onClick={() => this.tabs.next()}>Next</button> 
    </App> 
    ) 
    } 
} 

以上reasonbleアプローチは、フラックスを言ういくつかの集中状態管理ソリューションに切り替えることであろうに、インスタンスをタブに得ることができました。 Redux :)を見てください。

関連する問題