JSX
基本语法就不再赘述了, 下面介绍一些容易出现的坑.
1. 节点属性
如果往原生 html 元素里传入 HTML 规范里不存在的属性, React 不会显示它们. 如果需要使用自定义属性, 要加 data- 前缀.
<div data-custom-attribute="foo" />
然而任意属性支持自定义元素
<x-my-component custom-attribute="foo" />
Javascript 表达式
要使用 JavaScript 表达式作为属性值, 只需把这个表达式用一对大括号 ( { } ) 包起来, 不要用引号 ( " " ).
求值表达式本身与 JSX 没有多大关系, 是 JS 中的特性. 它是会返回值的表达式, 与语句有本质上的不同, 在编写 JSX 时, 在 { } 中不能使用语句(if 语句, for 语句等等). 我们不能直接使用语句, 但可以把语句包裹在函数求值表达式中运用. 建议把函数表达式独立出来, 在 { } 调用.
1. 条件判断的写法
你没法在 JSX 中使用 if-else 语句, 因为 JSX 只是函数调用和对象创建的语法糖. 在 { } 中使用, 是不合法的 JS 代码, 不过可以采用三元操作表达式
- class HelloMessage extends React.Component {
- render() {
- return <div>Hello {this.props.name ? this.props.name : "World"}</div>;
- }
- }
- ReactDOM.render(
- <HelloMessage />,
- document.getElementById('root')
- );
可以使用比较运算符 "||" 来书写, 如果左边的值为真, 则直接返回左边的值, 否则返回右边的值, 与 if 的效果相同.
- class HelloMessage extends React.Component {
- render() {
- return <div>Hello {this.props.name || "World"}</div>;}
- }
- ReactDOM.render(
- <HelloMessage />,
- document.getElementById('root')
- );
也可以使用变量来书写
- class HelloMessage extends React.Component {
- getName() {
- if (this.props.name)
- return this.props.name
- else
- return "world"
- }
- render() {
- var name = this.getName();
- return <div>Hello {name}</div>;
- }
- }
- ReactDOM.render(
- <HelloMessage />,
- document.getElementById('root')
- );
其中可以把变量去掉, 直接在 { } 中调用函数
- render() {
- return <div>Hello {this.getName()}</div>;
- }
2. 函数表达式
- // ( )有强制运算的作用
- class HelloMessage extends React.Component {
- render() {
- return <div>Hello {
- (function (obj) {
- if (obj.props.name)
- return obj.props.name
- else
- return "World"
- }(this))
- }</div>;
- }
- }
- ReactDOM.render(
- <HelloMessage name={"wzw"} />,
- document.getElementById('root')
- );
外括号 ")" 放在外面和里面都可以执行. 唯一的区别是括号执行完毕拿到的是函数的引用, 然后再调用; 括号放在外面的时候拿到的事返回值. 需传入(this).
3. 注释
JSX 里添加注释很容易; 它们只是 JS 表达式而已. 你只需要在一个标签的子节点内 (非最外层) 小心地用 { } 包围要注释的部分
- var content = (
- <Nav>
- {/* 一般注释, 用 {} 包围 */}
- <Person
- /* 多
- 行
- 注释 */
- name={window.isLoggedIn ? window.name : ''} // 行尾注释
- />
- </Nav>
- );
4. 样式
尽管在大部分场景下我们应该将样式写在独立的 CSS 文件中, 但是有时对于某个特定组件而言, 其样式相当简单而且独立, 那么也可以将其直接定义在 JSX 中. 在 JSX 中使用样式和真实的样式也很类似, 通过 style 属性来定义, 但和真实 DOM 不同的是, 属性值不能是字符串而必须为对象, 需要注意的是属性名同样需要驼峰命名法. 例如:
- var style = {
- color : "red",
- border : "1px solid #000"
- }
- class HelloMessage extends React.Component {
- render() {
- return <div>Hello {this.props.name}</div>;
- }
- }
- ReactDOM.render(
- <div style={style}>
- <HelloMessage name="worldsong"/>
- </div>,
- document.getElementById('root')
- );
JSX 扩展属性
不要改变 props
如果提前就知道了组件的属性的话, 写起来很容易. 例如 component 组件有两个动态的属性 foo 和 bar:
var component = <Component foo={x} bar={y} />;
为了解决这个问题, React 引入了属性扩展:
当需要拓展我们的属性的时候, 定义个一个属性对象, 并通过 {...props} 的方式引入, React 会帮我们拷贝到组件的 props 属性中. 重要的是 - 这个过程是由 React 操控的, 不是手动添赋值的属性.
- var props = {};
- props.foo = x;
- props.bar = y;
- var component = <Component {...props} />
需要覆盖的时候可以这样写:
- var props = { foo: 'default' };
- var component = <Component {...props} foo={'override'} />;
JSX 中容易出现的错误:
1style 属性
在 React 中写行内样式时, 不能采用引号的书写方式, 要这样写:
- ReactDOM.render(
- <div style={{color:'red'}}>
- xxxxx
- </div>,
- document.getElementById('root')
- );
2.HTML 转义
- var content='<strong>content</strong>';
- ReactDOM.render(
- <div>{content}</div>,
- document.getElementById('root')
- );
结果页面直接输出内容了:
2.png
React 默认会进行 HTML 的转义, 避免 XSS 攻击, 如果要不转义, 可以这么写:
- var content='<strong>content</strong>';
- ReactDOM.render(
- <div dangerouslySetInnerHTML={{__html: content}}></div>,
- document.getElementById('root')
- );
3. 自定义 HTML 属性
如果在编写 React 过程中使用了自定义属性, React 不会渲染的
如果需要使用自定义属性, 要加 data- 前缀.
4. 布尔值, Null 和 Undefined 被忽略
false,null,undefined 和 true 都是有效的子代, 但它们不会直接被渲染. 下面的表达式是等价的:
- <div />
- <div></div>
- <div>{false}</div>
- <div>{null}</div>
- <div>{undefined}</div>
- <div>{true}</div>
这在根据条件来确定是否渲染 React 元素时非常有用. 以下的 JSX 只会在 showHeader 为 true 时渲染 < Header />组件.
- <div>
- {showHeader && <Header />}
- <Content />
- </div>
值得注意的是, JavaScript 中的一些 "falsy" 值( https://developer.mozilla.org/en-US/docs/Glossary/Falsy)( 比如数字 0), 它们依然会被渲染. 例如, 下面的代码不会像你预期的那样运行, 因为当 props.message 为空数组时, 它会打印 0:
falsy 值是在 Boolean 上下文中认定可转换为 false 的值.
- <div>
- {props.messages.length &&
- <MessageList messages={props.messages} />
- }
- </div>
要解决这个问题, 请确保 && 前面的表达式始终为布尔值:
- <div>
- {props.messages.length> 0 &&
- <MessageList messages={props.messages} />
- }
- </div>
相反, 如果你想让类似 false,true,null 或 undefined 出现在输出中, 你必须先把它转换成字符串 相反, 如果你想让类似 false,true,null 或 undefined 出现在输出中, 你必须先把它转换成字符串
<div>
My JavaScript variable is {String(myVariable)}.
</div>
!!!React 必须声明
由于 JSX 编译后会调用 React.createElement 方法, 所以在你的 JSX 代码中必须首先声明 React 变量.
JSX 编译
- <div className="red">Children Text</div>;
- <MyCounter count={3 + 5} />;
- // Here, we set the "scores" attribute below to a JavaScript object.
- var gameScores = {
- player1: 2,
- player2: 5
- };
- <DashboardUnit data-index="2">
- <h1>Scores</h1>
- <Scoreboard className="results" scores={gameScores} />
- </DashboardUnit>;
3.png
HTML 标签对比 React 组件:
React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes).
要渲染 HTML 标签, 只需在 JSX 里使用小写字母的标签名.
- var myDivElement = <div className="foo" />;
- ReactDOM.render(
- myDivElement ,
- document.getElementById('root')
- );
要渲染 React 组件, 只需创建一个大写字母开头的本地变量.
- function UserGreeting(props) {
- return <h1>Welcome back!</h1>;
- }
- var myElement = <UserGreeting someProperty={true} />;
- ReactDOM.render(
- myElement ,
- document.getElementById('root')
- );
React 的 JSX 使用大, 小写的约定来区分本地组件的类和 HTML 标签.
! 注意:
由于 JSX 就是 JavaScript, 一些标识符像 class 和 for 不建议作为 XML 属性名. 作为替代, React DOM 使用 className 和 htmlFor 来做对应的属性.
来源: http://www.jianshu.com/p/a4c3535cd361