React.js实战之深入了解JSX
在项目中引入并使用 JSX
添加支持
插件支持
引入依赖
React提供的环境搭建工具演示
新建test项目
yarn start
可以将配置文件提出来
yarn eject
配置文件可读性差,因此不考虑使用这种现成方式写项目,跳过吧
JSX 是React 为JavaScript 语法带来的可选扩展,用于在JavaScript 代码中编写声明式XML 风格语法。
对于Web 项目而言,React 的JSX 提供了一组类似于HTML 的XML 标签,但在其他使用场景中,会使用其他组XML 标签来描述用户界面(如React with SVG、React Canvas和React Native)。转译后,XML 会被转换为针对React 库的函数调用。这行代码:
<h1>Hello World</h1>
会被转译为:
React.createElement("h1", null, "Hello World");
JSX 是可选的。但拥抱它会带来如下好处
- XML 包含特性的元素树非常适合表示UI。
- 能够更精确和更方便地呈现应用程序的结构。
- 是普通JavaScript,并不会改变这门语言的语义。
1 JSX 与HTML
对于Web 场景而言,JSX 看上去就像HTML,但它并不是HTML 规范的具体实现。React 的创造者只是让JSX 足够像HTML,这样就可以用来正确地描述Web 界面,并没有忽略这样一个事实,即它仍然应该遵循JavaScript 的风格和语法
2 JSX 和HTML 的不同之处
2.1 标签特性采取驼峰式大小写风格
例如,在HTML 中,输入标签可以包含一个可选的maxlengh 特性:<input type="text" maxlength="30"/>
在JSX 中,该特性应该写作maxLength(请注意大写字母“L”):return <input type="text" maxLength="30" />
2.2 所有元素都必须闭合
由于JSX 是XML,因此元素都必须闭合。诸如
和<img>这样的标签并不包含结束标签,需要自闭合。所以要使用<br/>
而不是<br>
,要使用<imgsrc="..."/>
而不是<imgsrc="...">
2.3 特性名称基于DOM API
这一点可能难以理解,但实际上却非常简单。在与DOM API 进行交互时,标签特性的名称可能会和在HTML 中使用时有所不同。其中一个例子是class 和className。例如,对于这段普通的HTML:<div id="box" class="some-class"></div>
如果你想要使用普通JavaScript 来操作DOM 并更改它的类名,你可能会编写这样的代码:document.getElementById("box").className="some-other-class"
在JavaScript 中,这个特性称为className 而不是class。由于JSX 只是JavaScript的一种语法扩展,它遵循了DOM 所定义的特性命名规范。同样的div 用JSX 来表示就应该是:return <div id="box" className="some-class"></div>
2.3 JSX 的怪异之处
JSX 偶尔也比较奇怪。针对在使用JSX 构建组件时可能会遇到的常见问题,本节汇总了一些小技巧、提示和策略来供你应对。
- 单一根节点
React 组件只能渲染一个根节点。想要了解这个限制的原因,我们先来看看render函数的一个返回示例:
return( <h1>Hello World</h1>
)
它会被转换成一条语句:
return React.createElement("h1",null,"Hello World");
但是,下面的代码却不是合法的:
return ( <h1>Hello World</h1>
<h2>Have a nice day</h2>
)
需要明确的是,这并非JSX 的限制,而是JavaScript 的一个特性:一条返回语句只能返回单个值,而在前面的代码中我们尝试返回两条语句(两次React.createElement 调用)。解决的方法非常简单:就像你在普通JavaScript 中会做的那样,将所有返回值包含到一个根对象中。
return ( <div>
<h1>Hello World</h1>
<h2>Have a nice day</h2>
</div>
)
它完全有效,因为它会被转换成:
return React.createElement("div",null, React.createElement("h1",null,"Hello World"),
React.createElement("h2",null," Have a nice day"),
)
它返回单个值,并且是通过合法的JavaScript 完成的。
- 条件语句
如果语句不兼容于JSX,看上去像是JSX 的限制所致,实际上却是因为JSX 只是普通的JavaScript
回顾一下JSX 是如何被转换为普通JavaScript
如下JSX
return ( <div className="salutation">Hello JSX</div>
)
会被转换成这样的JavaScript
return ( React.createElement("div",{className:"salutation"},"Hello JSX");
)
然而,如果尝试在JSX 的中间编写if 语句,例如:<div className={if (condition) { "salutation" }}>Hello JSX</div>
它就会被转换成一个非法的JavaScript 表达式,如图2-1 所示:
image
- 有什么解决方法?
尽管并无可能在JSX 中使用“if”语句,但仍有根据条件渲染内容的方法,包括使用三元表达式和将条件赋值给一个变量(空值和未定义的值都会被React 进行处理,JSX在转义时什么都不会输出)。
使用三元表达式
如果你有一个非常简单的表达式,可以使用三元形式:
render() { return (
<div className={condition ? "salutation" : ""}>
Hello JSX
</div>
)
}
这段代码会被转换成一段合法的JavaScript:
React.createElement("div",{className: condition ?"salutation" : ""}, "Hello JSX");
三元形式还可用来有条件地渲染整个节点:
<div> {condition ?
<span>Hello JSX</span>
: null}
</div>
将条件外置
如果三元表达式还不能应付你的要求,解决方法是不要在JSX 的中间使用条件。简单地将条件语句移动到外部(就像你在第2 章中隐藏和显示ContactItem 细节时所采取的方法)。
下面是原先的代码:
1. render() {
2. return (
3. <div className={if (condition) { "salutation" }}>
4. Hello JSX
5. </div>
6. )
7. }
将条件移动到JSX 的外部,就像:
render() { let className;
if(condition){
className = "salutation";
}
return (
<div className={className}>Hello JSX</div>
)
}
React 知道如何处理未定义的值,如果条件为假,它甚至不会在div 标签中创建class特性。
以上是 React.js实战之深入了解JSX 的全部内容, 来源链接: utcz.com/z/384126.html