Bra*_*rks 53 javascript reactjs
我在React文档中读到"if"类型语句不能在JSX代码中使用,因为JSX呈现为javascript的方式,它并没有像人们期望的那样工作.
但有没有理由为什么实现"if"组件是一个坏主意?它似乎从我最初的测试中运行良好,让我想知道为什么不经常这样做?
我的部分目的是尽可能地让反应开发,基于标记 - 尽可能少的javascript.对我而言,这种方法更像是一种"数据驱动"方法.
<script type='text/javascript' src="https://unpkg.com/react@0.11.0/dist/JSXTransformer.js"></script>
<script type='text/javascript' src="https://unpkg.com/react@0.11.0/dist/react-with-addons.js"></script>
<script type="text/jsx">
/** @jsx React.DOM */
var If = React.createClass({
displayName: 'If',
render: function()
{
if (this.props.condition)
return <span>{this.props.children}</span>
return null;
}
});
var Main = React.createClass({
render: function() {
return (
<div>
<If condition={false}>
<div>Never showing false item</div>
</If>
<If condition={true}>
<div>Showing true item</div>
</If>
</div>
);
}
});
React.renderComponent(<Main/>, document.body);
</script>Run Code Online (Sandbox Code Playgroud)
运行以上结果:
显示真实的项目
hug*_*omg 62
在JSX中,您不能将语句放在花括号中 - 仅表达式.如果您不知道JavaScript中表达式与语句之间的区别,请阅读本文.这个限制是因为JSX去了函数调用,你不能使用if语句作为JavaScript函数的参数.但是,您可以使用布尔运算符(&&,||和? :)来执行类似的工作.它们是表达式,因此它们可以适合JSX生成的构造函数调用,并且它们的短路评估与if语句中使用的相同.
<div>
{(true
? <div>Showing true item</div>
: <div>Never showing false item</div>
)}
</div>
<p>My name is {this.name || "default name"}</p>
Run Code Online (Sandbox Code Playgroud)
另外,React将把null它false作为一个"空组件"来处理,而不是在真正的DOM中呈现(目前它在幕后使用相同的noscript技巧).当您不想要"else"分支时,这很有用.有关详细信息,请参阅JSX中的False.
<div>
{shouldIncludeChild ? <ChildComponent/> : false}
</div>
Run Code Online (Sandbox Code Playgroud)
至于你询问的If组件,它遇到的一个问题是,即使条件为假,它也会以当前形式评估其子组件.如果条件为真,那么当If的主体才有意义时,这可能会导致错误:
<If condition={person !== null}>
//This code throws an exception if this.person is null
<div>{person.name}</div>
</If>
Run Code Online (Sandbox Code Playgroud)
您可以通过让if组件将body作为函数接收而不是作为子组件列表来解决这个问题,但它更详细:
<If condition={person !== null} body={function(){
return <div>{person.name}</div>
}/>
Run Code Online (Sandbox Code Playgroud)
最后,由于If组件是无状态的,因此您应该考虑使用普通函数而不是新的组件类,因为这会使"If"对React的协调算法透明.如果使用If组件,则a <div>和a <If><div>将被视为不兼容,React将执行完全重绘,而不是尝试将新组件与旧组件合并.
// This custom if function is for purely illustrative purposes
// However, this idea of using callbacks to represent block of code
// is useful for defining your own control flow operators in other circumstances.
function myCustomIf(condition, onTrue, onFalse){
onTrue = onTrue || function(){ return null }
onFalse = onFalse || function(){ return null }
if(condition){
return onTrue();
}else{
return onFalse();
}
}
<div>
{myCustomIf(person !== null, function(){
return <div>{person.name}</div>
})}
</div>
Run Code Online (Sandbox Code Playgroud)
Seb*_*ber 34
你不需要普通的JS.
maybeRenderPerson: function() {
var personName = ...;
if ( personName ) {
return <div className="person">{personName}</div>;
}
}
render: function() {
return (
<div className="component">
{this.maybeRenderPerson()}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
它有点冗长,但它允许在较小的,集中的块中轻松地分割逻辑.当组件开始变得复杂时,这是最可读的.
render: function() {
var personName = ...; // present or absent name, but never ""
return (
<div className="component">
{personName && (
<div className="person">{personName}</div>
)}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
如果测试变量可能是假的值0,""或者如此,则此语法可能非常危险false.特别是对于数字,如果要确保它呈现为0,则应该稍微修改测试:
render: function() {
var counter= ...; // number, can be 0
return (
<div className="component">
{(typeof counter !== 'undefined') && (
<div className="counter">{counter}</div>
)}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
当组件变得复杂时,拆分成多个较小的组件,并具有代码样式约定可以帮助保持其可读性:
render: function() {
var person= ...;
var counter= ...;
return (
<div className="component">
{person && (
<Person person={person}/>
)}
{(typeof counter !== 'undefined') && (
<Counter value={counter}/>
)}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
do功能无状态组件的表示法可用于表达性而不会失去可读性.您可以轻松地将大型组件拆分为使用该do表示法的非常小且集中的组件:
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}/>
}
Run Code Online (Sandbox Code Playgroud)
这有点像在JSX中使用模块模式,所以它非常灵活,但是它的样板很少.
要启用此功能,您需要ES7 stage 0编译工具,并且您最喜欢的IDE的支持可能尚不存在.
Cha*_*ira 16
你可以做这样的内联条件
{true && (
<div>render item</div>
)}
{false && (
<div>don't render item</div>
)}
Run Code Online (Sandbox Code Playgroud)
或者你可以使用var
var something;
if (true) {
something = <div>render item</div>
}
{something}
Run Code Online (Sandbox Code Playgroud)
实验性 ES7do语法非常适合这种情况。如果您使用 Babel,请启用该es7.doExpressions功能,然后:
render() {
var condition = false;
return (
<div>
{do {
if (condition) {
<span>Truthy!</span>;
} else {
<span>Not truthy.</span>;
}
}}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
见http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions
您也可以在适当的上下文中执行自执行功能(尽管在Babel的帮助下)!我更喜欢这种方式,因为不需要分配变量,并且您可以根据需要进行复杂设置(尽管出于可维护性考虑,您可能不应该这样做):
render() {
return (
<div>
<div>Hello!</div>
{() => {
if (this.props.isLoggedIn) {
return <Dashboard />
} else {
return <SignIn />
}
}()}
<div>Another Tag</div>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42456 次 |
| 最近记录: |