2017-06-06 107 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 :)。