有没有办法仅在单击按钮时更改<Block1> 中的组件?
是的。
解决这个问题的一种方法是让主要的顶级组件<Block1>,或者我们称之为<MainBlock>,成为一个有状态的组件,它维护状态并驱动确定渲染内容的逻辑。其他组件可能只是根据<MainBlock> 设置的状态标志呈现的无状态表示组件。
基本上,<MainBlock> 有一个状态标志,比如说isShowingNext,它用于确定渲染哪个部分(“下一个”或“上一个”),并通过按钮调用的操作设置该标志。
就按钮本身而言,它们附加了 onClick 侦听器,无论何时单击,都会在 <MainBlock> 和 <MainBlock> 中调用一个操作来更新状态标志并重新呈现正确的组件。
由于按钮几乎相同,我们可以将它们组合成一个按钮组件,例如<ToggleButton>,它将根据传递的标志有条件地呈现(“上一个”或“下一个”)(参见 第一种方法)。
根据您的用例,如果按钮(及其呈现逻辑)不太相似,您可以使用其中两个,例如 <ButtonPrev> 和 <ButtonNext>,其中一个或另一个由<MainBlock> 取决于州旗(参见第二种方法)。
第一种方法
jsFiddle sample
var MainBlock = React.createClass({
// initially we are showing the "previous" page
getInitialState() {
return {
isShowingNext: false
};
},
// action that updates the state flag to determine what gets rendered
handleUpdateIsShowingNext: function(isShowingNext) {
this.setState({
isShowingNext: isShowingNext
});
},
// render function that displays the proper template based on the state flag
render: function(){
var isShowingNext = this.state.isShowingNext;
return (
<div className="block">
{isShowingNext ? <ComponentNext/> : <ComponentPrev/>}
<ToggleButton isShowingNext={isShowingNext}
onUpdateIsShowingNext={this.handleUpdateIsShowingNext}
/>
</div>
);
}
});
// button for that toggles between "previous" or "next" page depending on the logic
var ToggleButton = React.createClass({
toggle: function(){
this.props.onUpdateIsShowingNext(!this.props.isShowingNext); // toggle the "isShowingNext" flag
},
render: function(){
var isShowingNext = this.props.isShowingNext;
if (isShowingNext) {
return <button className="button-prev" onClick={this.toggle}>Prev</button>;
} else {
return <button className="button-next" onClick={this.toggle}>Next</button>;
}
}
});
// representational component for the "previous" page
var ComponentPrev = React.createClass({
render: function(){
return <p className = "component-prev">This is ComponentPrev</p>;
}
});
// representational component for the "next" page
var ComponentNext = React.createClass({
render: function(){
return <p className = "component-next">This is ComponentNext</p>;
}
});
ReactDOM.render(<MainBlock/>, document.getElementById("container"));
第二种方法
jsFiddle sample
var MainBlock = React.createClass({
// initially we are showing the "previous" page
getInitialState() {
return {
isShowingNext: false
};
},
// returns the template for the "previous" page
getTemplateForPrev: function() {
return (
<div className="block">
<ComponentPrev/>
<ButtonPrev onUpdateIsShowingNext={this.handleUpdateIsShowingNext}/>
</div>
);
},
// returns the template for the "next" page
getTemplateForNext: function() {
return (
<div className="block">
<ComponentNext/>
<ButtonNext onUpdateIsShowingNext={this.handleUpdateIsShowingNext}/>
</div>
);
},
// action that updates the state flag to determine what gets rendered
handleUpdateIsShowingNext: function(isShowingNext) {
this.setState({
isShowingNext: isShowingNext
});
},
// render function that displays the proper template based on the state flag
render: function(){
return this.state.isShowingNext ? this.getTemplateForNext() : this.getTemplateForPrev();
}
});
// representational component for the "previous" page
var ComponentPrev = React.createClass({
render: function(){
return <p className = "component-prev">This is ComponentPrev</p>;
}
});
// button for the "previous" page
var ButtonPrev = React.createClass({
next: function(){
this.props.onUpdateIsShowingNext(true); // clicking "previous" makes isShowingNext be true
},
render: function(){
return <button className="button-prev" onClick={this.next}>Next</button>;
}
});
// representational component for the "next" page
var ComponentNext = React.createClass({
render: function(){
return <p className = "component-next">This is ComponentNext</p>;
}
});
// button for the "next" page
var ButtonNext = React.createClass({
previous: function(){
this.props.onUpdateIsShowingNext(false); // clicking "previous" makes isShowingNext be false
},
render: function(){
return <button className="button-next" onClick={this.previous}>previous</button>;
}
});
ReactDOM.render(<MainBlock/>, document.getElementById("container"));