问:有没有办法提供一个接口来访问给定可重用组件的公共方法?
场景:想象一下,我正在建立一个Tabs
组件。它位于父组件内,名为App
:
<App>
<Tabs />
<button id="previous">Previous</button>
<button id="next">Next</button>
</App>
正如您所看到的,有两个按钮可以与Tabs
组件进行交互,将其移动到上一个或下一个选项卡窗格。
我的实施包括将next()
和previous()
方法保留在Tabs
组件中:
export default class Tabs extends React.Component {
next() {}
previous() {}
}
问:如何将next()
和previous()
方法绑定到App
组件中的那些按钮?我可以编写Tabs
组件公开的某种界面吗?什么是最佳和干净方式?
编辑1 :...
编辑2 :Tabs
是一个“可重复使用”的组件。许多应用程序可以将其呈现在内
答案 0 :(得分:2)
您可以在父组件
中获得ref到Tabs实例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>
)
}
}
或者更合理的方法是切换到一些集中的状态管理解决方案说Flux。看看Redux:)。
答案 1 :(得分:2)
正如其他人所说,按钮位于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>
)
}
我认为此时引入Redux或任何其他状态库是不合理的。仅为您的标签组件管理全局状态是过度的。
答案 2 :(得分:1)
如果您的按钮作用于Tab
组件的元素,则它们应位于此组件内。然后,您可以使用state
的{{1}}支柱轻松更改组件的onPress
。
如果您仍希望将按钮保留在组件之外(即使我没有明确说明的原因),那么您应该考虑使用像Button
这样的商店在整个组件中保持“全局”状态。