三、jsx简化教程
1)使用 JSX 的好处
1.提供更加语意化且易懂的标签
与html对比
<!--HTML写法--> <form class="messageBox"> <textarea></textarea> <button type="submit"></button> </form> //jsx写法 <MessageBox />
1.1命令式 对比 声明式
React 思路认为使用 Component 比起模版(Template)和显示逻辑(Display Logic)更能实现关注点分离的概念,而搭配 JSX 可以实现声明式Declarative (注重 what to),而非命令式 Imperative (注重 how to)的程序编写方式
//命令式写法 if(userLikes()) { if(!hasBlueLike()) { removeGrayLike(); addBlueLike(); } } else { if(hasBlueLike()) { removeBlueLike(); addGrayLike(); } } //声明式写法 if(this.state.liked) { return (<BlueLike />); } else { return (<GrayLike />); }
2.更加简洁
虽然最终 JSX 会转换成 JavaScript,但使用 JSX 可以让程序看起来更加简洁,
//以下为使用 JSX <a href="https://facebook.github.io/react/">Hello!</a> //不使用jsx // React.createElement(元件/HTML标签, 元件属性,以对象表示, 子元件) React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')
3.结合原生 Js 语法
// const 为常数 const lists = ['JavaScript', 'Java', 'Node', 'Python']; class HelloMessage extends React.Component { render() { return ( <ul> {lists.map((result, index) => { return (<li key={index}>{result}</li>); })} </ul>); } }
2)JSX 用法摘要
1.环境设定与使用方式
1.1jsx使用方式
- 使用 browserify 或 webpack 等 CommonJS bundler 并整合babel 预处理
- 于浏览器端做解析
1.2加载 JSX 方式
两种加载方式:
//内嵌 <script type="text/babel"> ReactDOM.render( <div>hello react!!</div>, document.getElementById('example') ); </script> //从外部引入 <script type="text/jsx" src="main.jsx"></script>
2.标签用法
JSX 标签非常类似 XML ,可以直接书写。一般 Component 命名首字大写,HTMLTags 小写。
//以下是一个建立 Component 的 class class HelloMessage extends React.Component { render() { return ( <div> <p>Hello React!</p> <MessageList /> </div> ); } }
3.转换成 Js
JSX 最终会转换成浏览器可以读取的 JavaScript
转换规则:
React.createElement( string/ReactClass, // 表示 HTML 元素或是 React Component [object props], // 属性值,用对象表示 [children] // 接下来参数皆为元素子元素 )
解析前(特别注意在 JSX 中使用 JavaScript 表达式时使用 {} 括起,如下方范例的 text ,里面对应的是变数。若需希望放置一般文字,请加上 '' )
var text = 'Hello React'; <h1>{text}</h1> <h1>{'text'}</h1>
解析完后:
另外要特别要注意的是由于 JSX 最终会转成 JavaScript 且每一个 JSX 节点都对应到一个 JavaScript 函数,所以在 Component 的 render 方法中只能回传一个根节点(Root Nodes)。
例如:若有多个 <div> 要 render 请在外面包一个Component 或 <div> 、 <span> 元素。
var text = 'Hello React'; React.createElement("h1", null, "Hello React!");
4.注解(注释)
由于 JSX 最终会编译成 JavaScript,注解也一样使用 // 和 /**/ 当做注解方式
// 单行注解 /* 多行注解 */ var content = ( <List> {/* 若是在子元件注解要加 {} */} <Item /* 多行 注解 喔 */ name={window.isLoggedIn ? window.name : ''} // 单行注解 /> </List> );
5.属性
在 HTML 中,我们可以通过标签上的属性来改变标签外观样式,在 JSX 中也可以。
【注意】class 和 for 由于为 JavaScript 保留关键字用法,因此在 JSX中使用 className 和 htmlFor 替代。
class HelloMessage extends React.Component { render() { return ( <div className="message"> <p>Hello React!</p> </div> ); } }
5.1Boolean 属性
在 JSX 中预设只有属性名称但没设值为 true
//例如以下第一个 input 标签disabled 虽然没设值,但结果和下面的 input 为相同 <input type="button" disabled />; <input type="button" disabled={true} />; //反之,若是没有属性,则预设预设为 false : <input type="button" />; <input type="button" disabled={false} />;
6.扩展属性
在 ES6 中使用 ... 是迭代对象的意思,可以把所有对象对应的值迭代出来设定属性,但要注意后面设定的属性会盖掉前面相同属性:
var props = { style: "width:20px", className: "main", value: "yo", } <HelloMessage {...props} value="yo" /> // 等于以下 React.createElement("h1", React._spread({}, props, {value: "yo"} ), "Hello React!");
7.自定义属性
若是希望使用自定义属性,可以使用 data- :
<HelloMessage data-attr="xd" />
8.显示 HTML
通常为了避免信息安全问题,我们会过滤掉 HTML,若需要显示的话可以使用:
<div>{{_html: '<h1>Hello World!!</h1>'}}</div>
9.样式使用
在 JSX 中使用外观样式方法如下,第一个 {} 是 JSX 语法,第二个为JavaScript 对象。与一般属性值用 - 分隔不同,为驼峰式命名写法:
<HelloMessage style={{ color: '#FFFFFF', fontSize: '30px'}} />
10.事件处理
事件处理为前端开发的重头戏,在 JSX 中通过 inline 事件的绑定来监听并处理事件(注意也是驼峰式写法)
<HelloMessage onClick={this.onBtn} />
更多事件处理参考:https://reactjs.org/docs/events.html#supported-events