很多模版语言的框架(比如 vue、angular )都会内置一些条件语法,比如 ng-if、v-if 等,但是在 react 的 JSX 里面,没有这样的指令,它提供给我们更灵活的选择,但是这种灵活也会带来很多问题,我们今天一起来看几个避免这些问题的建议。
如果我们渲染的是一个列表,可能列表里的数据不为空的时候我们才会进行渲染,我们可能会写出下面的判断代码:
{data.length && <div>{data.map((d) => d)}</div>}
但是,如果 data 数组是空的,我们会在界面上看到一个 0 。
在 JavaScript 中,布尔运算符不会把它们的运算结果转换为布尔值,另外这和 && 的工作方式有关系,如果左边是个假值(比如 0 就是个假值),会立刻被返回,然后 React 会将这个 0 放入 dom 中,如果是布尔值(比如 false )就不会。
如果你要使用 && ,永远让左侧的值是个 Boolean 值:
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx
你也可以用三元运算符:
{data.length ? <div>{data.map((d) => d)}</div> : null}
&& 运算符比 || 具有更高的优先级,这就意味着你得小心处理同时包含这两种运算符的 jsx 语句:
你可能会写出下面的代码:
data.a || data.b && <div className="error" />
这样写就错了,上面的代码实际上等价于:
data.a || (data.b && <div className="error" />)
根据以前的经验,如果你的代码里有用到 || ,就建议将条件用括号括起来:
(data.a || data.b) && <div className="error" />
三元运算符可以帮助我们很好的切换两个 JSX ,但是一旦超过两个,你的逻辑很快就会进入嵌套地狱:
{isEmoji
? <EmojiButton />
: isCoupon
? <CouponButton />
: isLoaded && <ShareButton />}
你可能想把它用 && 重构一下,但是也会有一些重复的判断条件:
{isEmoji && < EmojiButton /> }
{isCoupon && < CouponButton /> }
{!isEmoji && !isCoupon && isLoaded && < ShareButton /> }
这时候,回到原始的 if / else 是个不错的选择,建议封装个函数:
const getButton = () => {
if (isEmoji) return <EmojiButton />;
if (isCoupon) return <CouponButton />;
return isLoaded ? <ShareButton /> : null;
};
通过 props 传递的 React 元素能不能用作条件判断呢,看看下面这个例子:
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};
最好不要这样做,因为 props.children 可能有几种不同的情况。
props.children 可能是一个空数组,例如 <Wrap>{[].map(e => <div />)}</Wrap> 。
那用 children.length 来判断?也不严谨,因为 children 也可能是单个元素: <Wrap><div /></Wrap> 。
React.Children.count(props.children) 支持单个和多个 children ,但是,你可能会认为 <Wrap>{false && 'hi'}{false && 'there'} 包含两个个元素,而实际上不是。
我们再来试试通过 React.Children.toArray(props.children) 删除无效的节点,例如 false 。但对于一个空片段,仍然是正确的: <Wrap><></><Wrap> 。
所以,为了避免出错,最好还是不要用了 ...
使用用单独的三元运算符分支编写的 JSX 感觉就像是完全独立的代码:
{hasItem ? <Item id={1} /> : <Item id={2} />}
你觉得 hasItem 变化时会发生啥?我的猜测是首先 <Item id={1} /> 卸载,然后 <Item id={2} /> 装载,因为我写了两个个单独的 JSX 标签。
然而, React 并不知道也不关心我写了啥,它所看到的只是 Item 相同位置的元素,所以它依然会保留挂载的实例,然后更新 props 。上面的代码实际上等价于 <Item id={hasItem ? 1 : 2} /> 。
当分支包含不同的组件时,比如 {hasItem ? <Item1 /> : <Item2 />} , React 会重新挂载,因为 Item1 无法更新为 Item2 。
上面的情况可能问题不大,管理好状态就好,可能比重新装载性能还好。
但是,如果是非受控组件,可能问题就大了:
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}
如果 mode 属性变化了,你会发现之前在 name 输入框输入的信息还在 ...
通常的解决方案是使用 key ,它会告诉 React 这是两个完全不一样的元素:
// remounts on change
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}
或者,使用 && 替代三元运算符可能会更清晰一点:
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }
相反,如果你在同一个逻辑元素上的条件 props 不太一样,你可以将条件分支拆分为两个单独的 JSX 标签来提高可读性:
// messy
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>
// maybe try:
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}
// or even
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}
// ^^ bonus: _move_ the element around the markup, no remount
{condition ? <Tag props1 /> : <Tag props2 />}
Tag
key
&&
参考:https://thoughtspile.github.io/2022/01/17/jsx-conditionals/
来源:https://mp.weixin.qq.com/s/1BX5xK0wpUDBSininJbYHw
公众号:code秘密花园
Vue 2.0中的render中使用JSX,由于Vue框架并没有特意地去支持JSX,Vue和JSX为什么能配合在一起使用呢? 很简单, 因为Vue支持虚拟DOM, 你可以用JSX或者其他预处理语言,只要能保证render方法正常工作即可。
JSX就是Javascript和XML结合的一种格式,利用HTML语法来创建虚拟DOM。将XML语法直接加入JS中,通过代码而非模板来高效的定义界面。之后JSX通过翻译器转换为纯JS再由浏览器执行。
本文会先解释一下JSX的工作原理,再介绍一下如何用不寻常的方式来使用JSX。
最近选用的框架iview表单组件的render写法让人有点不习惯,尤其是在写比较复杂的逻辑的时候,还是感觉模 板式的写法比较方便且可读性较强。而render函数除了支持配置写法外,还支持jsx的写法。由于之前有用过react,因此对jsx并不陌生,可以直接上手。
react中基本都使用JSX来开发,但JSX其实是javascript的一种语法糖。语法糖就是提供了一种全新的方式书写代码,但是其实现原理与之前的写法相同。
脚手架工具:选用React官方推荐的脚手架工具create-react-app,安装npm install create-react-app -g。项目初始化步骤:
不仅仅是在React(或受JSX启发模板),对于在各种框架中进行模板化,JSX是如今一个非常受欢迎的选择。然而,如果你不喜欢使用JSX,或者你的项目想避免使用它,又或者只是受好奇心驱使
JSX就是Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析.
JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模版语言,但它具有 JavaScript 的全部功能。Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。
这被称为 JSX,是一个 JavaScript 的语法扩展。建议在 React 中配合使用 JSX,JSX 可以生成 React “元素”,而且JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模版语言,但它具有 JavaScript 的全部功能。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!