Javascript 如何使用Facebook React'拥有条件元素并保持干燥;是JSX吗?
如何选择在JSX中包含元素?下面是一个使用横幅的示例,如果该横幅已传入,则该横幅应位于组件中。我想要避免的是在if语句中重复HTML标记Javascript 如何使用Facebook React'拥有条件元素并保持干燥;是JSX吗?,javascript,reactjs,react-jsx,Javascript,Reactjs,React Jsx,如何选择在JSX中包含元素?下面是一个使用横幅的示例,如果该横幅已传入,则该横幅应位于组件中。我想要避免的是在if语句中重复HTML标记 render: function () { var banner; if (this.state.banner) { banner = <div id="banner">{this.state.banner}</div>; } else { banner = ????? }
render: function () {
var banner;
if (this.state.banner) {
banner = <div id="banner">{this.state.banner}</div>;
} else {
banner = ?????
}
return (
<div id="page">
{banner}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
render:function(){
瓦尔旗;
如果(本州横幅){
banner={this.state.banner};
}否则{
横幅=?????
}
返回(
{banner}
废话废话。。。
);
}
只需将横幅保留为未定义,它不会被包括在内。这怎么办。让我们定义一个简单的帮助If
组件
var If = React.createClass({
render: function() {
if (this.props.test) {
return this.props.children;
}
else {
return false;
}
}
});
并以这种方式使用它:
render: function () {
return (
<div id="page">
<If test={this.state.banner}>
<div id="banner">{this.state.banner}</div>
</If>
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
你使用它时必须小心。我建议阅读其他答案,寻找替代(更安全的)方法
更新2:回顾过去,这种方法不仅危险,而且极其麻烦。这是一个典型的例子,当一个开发人员(我)试图将他所知道的模式和方法从一个区域转移到另一个区域,但实际上不起作用(在本例中是其他模板语言)
如果需要条件元素,请按以下方式执行:
render: function () {
return (
<div id="page">
{this.state.banner &&
<div id="banner">{this.state.banner}</div>}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
<h3>{this.state.banner.title || 'Default banner title'}</h3>
当“if”分支中有多个元素时,此组件工作:
var Display=React.createClass({
渲染:函数(){
如果(!this.props.when){
返回false;
}
返回React.DOM.div(null,this.props.children);
},
});
用法:
render:function(){
返回(
正在加载某些内容。。。
Elem1
Elem2
加载
Elem3
Elem4
);
}
另外,有人认为这些组件不利于代码读取。但在我看来,使用javascript的Html更糟糕如果样式组件是危险的,因为代码块总是在不考虑条件的情况下执行。例如,如果
banner
为null
,这将导致null异常:
//dangerous
render: function () {
return (
<div id="page">
<If test={this.state.banner}>
<img src={this.state.banner.src} />
</If>
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
//危险
渲染:函数(){
返回(
废话废话。。。
);
}
另一个选项是使用内联函数(特别适用于else语句):
render:function(){
返回(
{函数(){
如果(本州横幅){
返回{this.state.banner}
}
}.叫(这个)}
废话废话。。。
);
}
react的另一个选项:
render:function(){
返回(
{this.state.banner&&
{this.state.banner}
}
废话废话。。。
);
}
我做了一些简化,基本上,它允许您将
条件定义为标记,然后将它们编译成三元ifs,这样
中的代码只有在条件为真时才能执行。只需添加另一个选项-如果您喜欢/容忍coffee脚本,您可以使用coffee react编写JSX,在这种情况下,if/else语句是可用,因为它们是coffee脚本中的表达式,而不是语句:
render: function () {
return (
<div id="page">
{function(){
if (this.state.banner) {
return <div id="banner">{this.state.banner}</div>
}
}.call(this)}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
render: ->
<div className="container">
{
if something
<h2>Coffeescript is magic!</h2>
else
<h2>Coffeescript sucks!</h2>
}
</div>
render:->
{
如果有什么
咖啡脚本很神奇!
其他的
咖啡糟透了!
}
我个人认为()中显示的三元表达式是符合ReactJs标准的最自然的方式
请参见下面的示例。乍一看有点凌乱,但效果相当不错
<div id="page">
{this.state.banner ? (
<div id="banner">
<div class="another-div">
{this.state.banner}
</div>
</div>
) :
null}
<div id="other-content">
blah blah blah...
</div>
</div>
{这个州的旗帜(
{this.state.banner}
) :
空}
废话废话。。。
&&+代码样式+小组件
这个简单的测试语法+代码样式约定+小型的重点组件对我来说是最可读的选项。您只需特别注意错误值,如false
、0
或“
”
render:function(){
var person=。。。;
var计数器=。。。;
返回(
{个人&&(
)}
{(计数器类型!=“未定义”)&&(
)}
);
}
做记号
ES7 stage-0 do表示法语法也非常好,当IDE正确支持时,我将最终使用它:
const Users = ({users}) => (
<div>
{users.map(user =>
<User key={user.id} user={user}/>
)}
</div>
)
const UserList = ({users}) => do {
if (!users) <div>Loading</div>
else if (!users.length) <div>Empty</div>
else <Users users={users}/>
}
constusers=({Users})=>(
{users.map(user=>
)}
)
const UserList=({users})=>do{
如果(!用户)正在加载
如果(!users.length)为空,则为else
其他的
}
这里有更多详细信息:实验性ES7
do
语法使这变得容易。如果您使用的是Babel,请启用es7.doExpressions
功能,然后:
render() {
return (
<div id="banner">
{do {
if (this.state.banner) {
this.state.banner;
} else {
"Something else";
}
}}
</div>
);
}
render(){
返回(
{do{
如果(本州横幅){
这个州的旗帜;
}否则{
“其他东西”;
}
}}
);
}
请参见还有一个非常干净的单线版本{this.props.product.title | |“无标题”} 即:
render:function(){
返回(
{this.props.product.title | |“无标题”}
);
}
还有另一种解决方案:
var节点=require('react-if-comp');
...
render:function(){
返回(
废话废话。。。
);
}
我最近做了一个改进,仅当谓词通过时才安全地呈现元素
{renderIf(1 + 1 === 2)(
<span>Hello!</span>
)}
{renderIf(1+1==2)(
你好
)}
或
const ifUniverseIsWorking=renderIf(1+1==2);
//...
{如果你正在工作(
你好
)}
你也可以这样写
{ this.state.banner && <div>{...}</div> }
{this.state.banner&&{…}
如果您的
state.banner
为null
或未定义
,则跳过条件的右侧。大多数示例都带有一行有条件呈现的“html”。这对我来说似乎是可读的
const Users = ({users}) => (
<div>
{users.map(user =>
<User key={user.id} user={user}/>
)}
</div>
)
const UserList = ({users}) => do {
if (!users) <div>Loading</div>
else if (!users.length) <div>Empty</div>
else <Users users={users}/>
}
render() {
return (
<div id="banner">
{do {
if (this.state.banner) {
this.state.banner;
} else {
"Something else";
}
}}
</div>
);
}
render: function() {
return (
<div className="title">
{ this.props.product.title || "No Title" }
</div>
);
}
var Node = require('react-if-comp');
...
render: function() {
return (
<div id="page">
<Node if={this.state.banner}
then={<div id="banner">{this.state.banner}</div>} />
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
{renderIf(1 + 1 === 2)(
<span>Hello!</span>
)}
const ifUniverseIsWorking = renderIf(1 + 1 === 2);
//...
{ifUniverseIsWorking(
<span>Hello!</span>
)}
{ this.state.banner && <div>{...}</div> }
render: function(){
return <div id="page">
//conditional statement
{this.state.banner ? <div id="banner">{this.state.banner}</div> : null}
<div id="other-content">
blah blah blah...
</div>
</div>
}
render: function () {
return (
<div id="page">
{this.state.banner ? <div id="banner">{this.state.banner}</div> : ''}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
class App extends React.Component {
constructor (props) {
super(props);
this._renderAppBar = this._renderAppBar.bind(this);
}
render () {
return <div>
{_renderAppBar()}
<div>Content</div>
</div>
}
_renderAppBar () {
if (this.state.renderAppBar) {
return <AppBar />
}
}
}
renderBanner: function() {
if (!this.state.banner) return;
return (
<div id="banner">{this.state.banner}</div>
);
},
render: function () {
return (
<div id="page">
{this.renderBanner()}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
{(() => {
if (isEmpty(routine.queries)) {
return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
} else if (this.state.configured) {
return <DeviceList devices={devices} routine={routine} configure={() => this.setState({configured: false})}/>
} else {
return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
}
})()}
render() {
return (
<div id="page">
{(() => (
const { banner } = this.state;
if (banner) {
return (
<div id="banner">{banner}</div>
);
}
// Default
return (
<div>???</div>
);
))()}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
function() {
}()
(function() {
}())
import React, { Component } from 'react';
// you should use ReactDOM.render instad of React.renderComponent
import ReactDOM from 'react-dom';
class ToggleBox extends Component {
constructor(props) {
super(props);
this.state = {
// toggle box is closed initially
opened: false,
};
// http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html
this.toggleBox = this.toggleBox.bind(this);
}
toggleBox() {
// check if box is currently opened
const { opened } = this.state;
this.setState({
// toggle value of `opened`
opened: !opened,
});
}
render() {
const { title, children } = this.props;
const { opened } = this.state;
return (
<div className="box">
<div className="boxTitle" onClick={this.toggleBox}>
{title}
</div>
{opened && children && (
<div class="boxContent">
{children}
</div>
)}
</div>
);
}
}
ReactDOM.render((
<ToggleBox title="Click me">
<div>Some content</div>
</ToggleBox>
), document.getElementById('app'));
{opened && <SomeElement />}
true && true && 2; // will output 2
true && false && 2; // will output false
true && 'some string'; // will output 'some string'
opened && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise
const Conditional = ({ condition, render }) => {
if (condition) {
return render();
}
return null;
};
class App extends React.Component {
constructor() {
super();
this.state = { items: null }
}
componentWillMount() {
setTimeout(() => { this.setState({ items: [1,2] }) }, 2000);
}
render() {
return (
<Conditional
condition={!!this.state.items}
render={() => (
<div>
{this.state.items.map(value => <p>{value}</p>)}
</div>
)}
/>
)
}
}
const If = ({children, show}) => show ? children : null
<If show={true}> Will show </If>
<If show={false}> WON'T show </div> </If>
{ condition && what_to_render }
render() {
const { banner } = this.state;
return (
<div id="page">
{ banner && <div id="banner">{banner}</div> }
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
export default function ReactIf(props: {condition: boolean, children: React.ReactNode }) {
return props.condition ? <React.Fragment>{props.children}</React.Fragment> : <React.Fragment/>;
}