某些组件包含Tabs
Tab
s:
class App {
render() {
<div>
<p>Tabs here:</p>
<Tabs>
<Tab name="Page 1"> .. content here .. </Tab>
<Tab name="Page 2"> .. content here .. </Tab>
<Tab name="Page 3"> .. content here .. </Tab>
</Tabs>
</div>
}
}
Tabs
负责大部分标记:
class Tabs {
click() {
// I want the Tab component, because I want to tab.setState()
// `this` is not a `Tab` object
}
render() {
return (
( print the tab labels: )
<ul>
{ this.props.children.map(tab =>
// >>> `tab` is not a `Tab` object <<<
<li><a onClick={ this.click.bind(tab) } href="#">{ tab.props.name }</a></li>
) }
</ul>
( print the tab content: )
{ this.props.children }
);
}
}
Tab
本身很少,也许什么都没有:
const Tab = ({children}) => <div>{ children }</div>;
Tabs.click
如何知道点击了哪个Tab
。如果我click.bind(tab)
它是子对象,而不是Tab对象。如果我click.bind(this)
它是Tabs
对象。
这可能是一种非常冗长的方式,可以解释为什么props.children
不包含Component对象,而是一种代理(?)子对象。它确实有道具,但没有方法,状态等。
编辑1:
在这个例子中,我想让Tab
决定如何呈现自己:一次作为标签链接,一次作为标签内容。标签将负责调用渲染方法,但Tab会知道如何。正如您在Tabs.render()
中看到的,有2个渲染。如果可以做到这一点,那就太好了:
<ul>
{ this.props.children.map(tab => tab.renderLink()) }
</ul>
{ this.props.children.map(tab => tab.renderContent()) }
or just
{ this.props.children }
because content is the normal render
但是Tabs
无法做到这一点,因为Tab
没有children
个对象......为什么?
答案 0 :(得分:0)
嗯,有几种方法可以实现这一目标。首先,你是对的 - 因为你在map
中使用了ES6箭头功能,this
并没有反弹 - 它继承了&#34;继承& #34;从封闭的范围(我认为,从技术上讲,它不那么继承而且更多只是保持不变 - 没有改变)。
首先,不要在render方法中绑定,而是在构造函数中绑定click
。
constructor(props) {
super(props);
this.click = this.click.bind(this);
}
或使用ES6箭头功能
click = (event) => {...}
虽然这并不能直接解决您的问题,但它会清除因使用绑定回调而产生的上下文混乱。
从那里,您可以使用event.target
。
您也可以使用partials - bind
方法接受附加参数,这些参数前缀为绑定函数的参数。这看起来像这样:
render (
<div>
{ this.props.children.map((tab) => {
<a <li><a onClick={ this.click.bind(null, tab) } href="#">{ tab.props.name }</a></li>
}) }
);
您还需要调整click
方法以接受标签:click(tab, event)
我也不认为这是明智的,甚至建议从其他组件中弄乱组件的状态。为什么不使用Tab
组件?传递Tabs
onClick
作为道具并处理此类点击事件......
class Tab extends React.Component {
onClick = (event) => {
this.setState({...}); // Tab onClick
if (this.props.onClick) this.props.onClick(); // Tabs onClick
}
}
编辑:工作示例
Tabs
上课
class Tabs extends React.Component {
onTabClick = (tab) => {
tab.setState({ test: true });
}
render() {
return (
<div>
{ this.props.children.map((tab) => {
return React.cloneElement(tab, {
onClick: this.onTabClick
});
}) }
</div>
);
}
}
Tab
上课
class Tab extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
onClick = (event) => {
console.log(event);
event.preventDefault();
if (this.props.onClick) {
this.props.onClick(this);
}
}
render() {
return <div>{ !this.state.test && <a href={ this.props.url } onClick={ this.onClick }>{ this.props.label }</a> }</div>;
}
}
示例标签
<Tabs>
<Tab url="http://www.google.com" label="Google" />
<Tab url="http://www.google.com" label="Google" />
</Tabs>
虽然它再次引发了这个问题 - 为什么不在Tab
类中设置状态呢?为什么需要在父母中设置孩子的状态? Can that state not be maintained by the parent (using this.setState(...)
and passed into the child as a prop?