Javascript 反应条件渲染模式
我已经实现了一个模态组件,它在屏幕上显示一个模态对话框。通常,模态将有条件地显示。有两种方法可以在渲染函数中执行此操作:Javascript 反应条件渲染模式,javascript,reactjs,Javascript,Reactjs,我已经实现了一个模态组件,它在屏幕上显示一个模态对话框。通常,模态将有条件地显示。有两种方法可以在渲染函数中执行此操作: render(){ ... <Modal show={this.state.showModal}> // something in modal </Modal> } render(){ ... //情态的东西 } 在模态组件中,我使用this.props.show向其自身添加一个不同的类。如果该值为false
render(){
...
<Modal show={this.state.showModal}>
// something in modal
</Modal>
}
render(){
...
//情态的东西
}
在模态组件中,我使用this.props.show向其自身添加一个不同的类。如果该值为false,则将添加一个display:none以隐藏模式
另一种方式是这样的:
render(){
...
{ this.state.showModal &&
(<Modal>
// something in modal
</Modal>)
}
}
render(){
...
{this.state.showmodel&&
(
//情态的东西
)
}
}
这将使用showmodel
来决定是否在渲染中添加模式
我想弄清楚的是:
我想也许没有一个确定的答案,哪种方式更好。也许这只是个人的选择 第一个示例始终呈现模式,但使用CSS隐藏/显示模式 第二个示例仅在显示模式时将其插入DOM,否则它根本不会显示在DOM中
我宁愿不渲染它,除非它是可见的(第二个例子),但我认为这两种方式都不重要。第二个示例现在也有更少的道具,因此模态组件更简单 答案在于模态组件的实现。我希望它的
render
方法使用show
prop来正确优化标记。您应该对其进行优化,以在未显示时消除大部分标记
为什么?
在Modal中实现优化简化了它的使用,其他组件不能意识到/担心渲染它的成本
编辑:
因为我们使用的是React,所以与它的dom标记的成本相比,在v-dom中使用虚拟模态组件的成本可以忽略不计。因此,即使您的其他组件最终在其v-dom中使用show=false保持模态,这也没关系。我也更喜欢第二种方法。即使React将在DOM中添加额外元素的负面影响降至最低,但最好不要渲染本来不需要的元素。我将扩展这种想法,提取在单独函数中显示/隐藏模态的逻辑,并在render中调用它
render: function(){
...
{this.renderModal()}
},
renderModal: function(){
...
{this.state.showModal && (<Modal />)}
}
render:function(){
...
{this.renderModal()}
},
renderModal:function(){
...
{this.state.showmodel&&()}
}
这使您可以灵活地在单个位置添加附加条件,并使渲染功能保持较小且易于理解。我在前一段时间回答了一个与 从那以后,我花了很多时间和React在一起,并从中吸取了一些教训 我发现这种处理情态动词的通用方法非常有效:使用一个完全受控的“哑”组件,它需要3个道具
- 显示:布尔-模态是否可见
- 关闭:函数-模态需要回调才能关闭自身
- 子节点:节点-模态的内容
要回答您关于两者区别的问题,IMO选项1提供了一个更干净、更灵活的API,而选项2则更简单 使用选项1,您可以使用CSS或从
返回null
来隐藏/显示。我建议返回null
,因为模式内容不会被呈现,而不是通过CSS呈现和“隐藏”它们
选项2强制使用更详细的“JSX方式”有条件地呈现,我认为这在很多情况下都是合适的。然而,我觉得模态的概念值得隐藏/显示为
组件API(道具/方法等)的一部分
为什么要传递
close
prop/callback?
考虑到大多数模态都有用户体验,例如关闭事件,例如:按[ESC],单击“x”,在模态外部单击,等等。。。在我下面的示例中,需要通过传递close
prop/callback来通知模态如何“关闭自身”
代码示例
//简单、完全受控的模态组件
const Modal=React.createClass({
render(){
常数{
show,//Boolean-模式是否可见?
close,//Function-模态需要一个函数来“关闭自身”
children,//node-模式的内容
}=这是道具;
return!show?空:(
x
{儿童}
);
}
});
const UsesModal=React.createClass({
设置编辑(编辑){
this.setState({editing});
},
render(){
//“编辑”可以来自任何地方。
//可能来自道具,
//或者作为州政府在当地管理,真的是在任何地方。。。。
const{editing}=this.state;
返回(
一些很棒的组件
this.setEditing(true)}>Show Modal!
this.setEditing(false)}>
一些很棒的模态内容…基于UsesModal.state.editing显示
);
}
});
如果你想让模态管理自己的状态,你可以用稍微聪明一点的组件来包装“哑”模态,并利用refs和“公共组件方法”(尽管我发现坚持简化方法通常会减少头痛和后悔;)
const SmarterModal=React.createClass({
关闭(){
this.setState({show:false});
},
开(){
this.setState({show:true});
},
render(){
const{children}
// The simple, fully controlled Modal component
const Modal = React.createClass({
render() {
const {
show, // Boolean - Is the modal visible?
close, // Function - The modal needs a function to "close itself"
children, // node - The contents of the modal
} = this.props;
return !show ? null : (
<div className="some-class-for-styling">
<a onClick={close}>x</a>
{children}
</div>
);
}
});
const UsesModal = React.createClass({
setEditing(editing) {
this.setState({editing});
},
render() {
// `editing` could come from anywhere.
// Could be derived from props,
// or managed locally as state, anywhere really....
const {editing} = this.state;
return (
<div>
<h1>Some Great Component</h1>
<a onClick={() => this.setEditing(true)}>Show Modal!</a>
<Modal show={editing} close={() => this.setEditing(false)}>
Some great modal content... show based on UsesModal.state.editing
</Modal>
</div>
);
}
});
const SmarterModal = React.createClass({
close() {
this.setState({show: false});
},
open() {
this.setState({show: true});
},
render() {
const {children} = this.props;
const {show} = this.state;
return (
<Modal show={show} close={this.close}>
{children}
</Modal>
);
}
});
const UsesSmarterModal = React.createClass({
render() {
return (
<div>
<h1>Some Great Component</h1>
<a onClick={() => this.refs.my_smarter_modal.open()}>Show Modal!</a>
<SmarterModal ref="my_smarter_modal">
Some great modal content... show based on SmarterModals own internal state
</SmarterModal>
</div>
);
}
});
var Node = require('react-if-comp');
...
var Test = React.createClass({
render: function() {
return <Node if={this.state.showModal}
then={<Modal>// something in modal</Modal>} />;
}
});
import { Layer, LayerContext } from 'react-layer-stack'
// ... for each `object` in array of `objects`
const modalId = 'DeleteObjectConfirmation' + objects[rowIndex].id
return (
<Cell {...props}>
// the layer definition. The content will show up in the LayerStackMountPoint when `show(modalId)` be fired in LayerContext
<Layer use={[objects[rowIndex], rowIndex]} id={modalId}> {({
hideMe, // alias for `hide(modalId)`
index } // useful to know to set zIndex, for example
, e) => // access to the arguments (click event data in this example)
<Modal onClick={ hideMe } zIndex={(index + 1) * 1000}>
<ConfirmationDialog
title={ 'Delete' }
message={ "You're about to delete to " + '"' + objects[rowIndex].name + '"' }
confirmButton={ <Button type="primary">DELETE</Button> }
onConfirm={ this.handleDeleteObject.bind(this, objects[rowIndex].name, hideMe) } // hide after confirmation
close={ hideMe } />
</Modal> }
</Layer>
// this is the toggle for Layer with `id === modalId` can be defined everywhere in the components tree
<LayerContext id={ modalId }> {({showMe}) => // showMe is alias for `show(modalId)`
<div style={styles.iconOverlay} onClick={ (e) => showMe(e) }> // additional arguments can be passed (like event)
<Icon type="trash" />
</div> }
</LayerContext>
</Cell>)
// ...