2017-06-06 56 views
0

問:有什麼辦法可以提供從給定的可重用組件訪問公共方法的接口?陣營組件接口方法

情景:假設我是一個層樓高組件Tabs。它位於一個父組件內,稱爲App

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

正如你可以看到有兩個按鈕,應與Tabs組件進行交互,將它移動到一個或下一個選項卡窗格。

我的實現在於憋Tabs組件next()previous()方法:

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

問:我怎樣才能結合next()previous()方法,這些按鈕裏面App的組成部分?我能寫一些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組件都將具有其自己的狀態和選項卡。如果你想讓你的currentTab狀態來自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> 
) 
} 

我不認爲這是有道理的,你引進終極版或在這一點上任何其他國家圖書館。僅僅爲你的標籤組件管理全局狀態是矯枉過正的。

+1

太棒了。經過一番思考後,這種方法更具「反應性」。謝謝!我結束了這個解決方案。 <3 – Richard

1

如果您的按鈕上Tab組成要素採取行動,那麼他們應該是這個組件中。然後,您可以輕鬆地與onPress道具的Button的改變你的組件的state

如果你仍然想保持你的按鈕你的組件之外(即使我沒有看到爲一個明確的理由),那麼你應該考慮使用像Redux商店跨越維持「全球性」的狀態你的組件。

+0

當將全球方法作爲解決方案時,Redux似乎混亂不堪。 我的意思是,它是可擴展的嗎?我不應該在'Tabs'上下文中保留'Tabs'動作,提供某種接口來處理這個? – Richard

+1

你只需要正確使用Redux。例如,您將擁有一個帶有「GO_TO_NEXT_TAB」和「GO_TO_PREVIOUS_TAB」動作的「NavigationReducer」。但是對於這個用例,再一次,你應該真的把你的按鈕嵌入到你的Tabs組件中,因爲它們與它有關。 – 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> 
    ) 
    } 
} 

還是比較講理的做法是切換到一些集中的國家管理解決方案,說助焊劑實例的標籤頁。看看Redux :)。