我在React文档中读到,在JSX代码中不能使用"if"类型语句,因为JSX呈现为javascript的方式,它并不像人们预期的那样有效.

但是,有什么理由认为实现"如果"组件是个坏主意吗?从我最初的测试来看,它似乎工作得很好,这让我想知道为什么不经常这样做?

我的部分意图是让react开发尽可能基于标记,尽可能少使用javascript.在我看来,这种方法更像是一种"数据驱动"的方法.

你可以check it out here on JS Fiddle

<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>显示真实项目</div>
             </If>
          </div>
        );
    }
});

React.renderComponent(<Main/>, document.body);
</script>

在中运行上述结果:

显示真实项目

推荐答案

查看react文档中的If-Else in JSX部分.

在JSX中,不能将语句放在大括号中,只能放在表达式中.如果你不知道JavaScript中表达式和语句之间的区别,请阅读这article条.这个限制是因为JSX会分解成函数调用,在JavaScript中不能使用if语句作为函数的参数.但是,您可以使用布尔运算符(&&||? :)来完成类似的工作.它们是表达式,因此可以放入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>

此外,React将nullfalse视为"空组件",不会在真实DOM中渲染(目前它在幕后使用相同的noscript技巧).当您不需要"else"分支时,这很有用.详情见False in JSX.

<div>
    {shouldIncludeChild ? <ChildComponent/> : false}
</div>

至于你提到的If组件,它有一个问题,就是在它当前的形式下,即使条件是错误的,它也会判断它的子组件.当If主体仅在条件为真时才有意义时,这可能会导致错误:

<If condition={person !== null}>
    //This code throws an exception if this.person is null
    <div>{person.name}</div>
</If>

您可以通过让if组件作为函数而不是子组件列表接收正文来解决这个问题,但它更详细:

<If condition={person !== null} body={function(){
    return <div>{person.name}</div>
}/>

最后,由于IF组件是无状态的,所以应该考虑使用一个纯函数而不是一个新的组件类,因为这会使"IF"透明的react 协调算法.如果使用If组件,则<div><If><div>将被视为不兼容,React将执行完全重画,而不是try 将新组件与旧组件合并.

// 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>

Reactjs相关问答推荐

导致类型错误的调度不是函数";

如何创建react router v6的自定义子路由?

在下一个js中使用ESTAccountWithEmailAndPassword函数时循环

如何访问子集合中的文档?

REACTION 18功能组件正在开发中的S

在transformResponse中使用来自其他查询的缓存

Reaction上下文值无法传递给其他组件

如何使用 React 获取表单中的所有值?

单击按钮不会切换组件(当按钮和组件位于两个单独的文件中时)

Next.js `getLayout` 函数没有被调用

React 组件列表中的第一个计时器正在获取值 NaN

使用 Vite 的 React 中的路由无法正常工作(构建中)

Reactjs 表单未反映提交时的更改

从 API 中提取映射数组后出现重复元素

为什么此代码中的 useState 不更新(文本更新但 id 不更新)?

react-admin useGetIdentity 只返回全名,id 未定义 头像未定义

react 路由dom没有路由匹配位置错误/在路由中制作组件

您无权使用阻止 webRequest 侦听器.请务必在 list 中声明 webRequestBlocking 权限

npm init vite@latest 和 npm init vite 有什么区别?

ClearInterval 在 React 中的 useRef 没有按预期工作