1147 字
6 分钟
01.JSX核心语法
JSX示例语法
我们在以往的学习中经常可以看到以下的代码:
const question = 'why'
const age = 18
const height = 1.8
const func = function() {
}
const obj = {}
但我们却没见过这样的代码:
const element = <h1>Hello World!</h2>
像这样的代码,就是JSX的语法。它要求我们必须引入“babel”。
<script crossorigin src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
// 示例代码
</script>
如若不引入,那你所使用的仍然是普通的JS代码。
什么是JSX?
JSX是JavaScript的语法扩展,它用于描述UI界面,并且使其可以和JS融合在一起使用(All in JS)。
React认为渲染逻辑本质上与其他UI逻辑存在内在耦合,相互的依赖非常强,所以React并没有将他们分离,而是将其组合为了组件(Component)。
JSX书写规范
JSX的顶层只能有一个根元素;
为了方便阅读,我们通常在JSX的外层包裹一个小括号();
JSX的标签可以是单标签,也可以是双标签。
<App/>
<App></App>
- JSX的注释:
<div>
<h1>该内容视为在JSX环境下</h1>
{/* <h2>Hello World</h2> */}
</div>
- JSX中嵌入数值:
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
name: 'why',
names: ['abc', 'cba', 'nba'],
}
}
render() {
return (
<div>
<h2>{this.state.name}</h2>
<h2>{this.state.names}</h2> {/* abccbanba */}
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector('#app'))
</script>
JSX的嵌入数据不能显示null、undefined、布尔值(true、false)。因为在真实渲染中,我们会进行一些真实判断,比如在使用一些三元运算符时,结果可能为null,这时页面中不应该呈现“null”字符,而是应该为空。
const flag = false
(
...
{ flag ? 'Flag is true.' : null }
{ flag && 'Flag is true' }
)
- 对象不能作为JSX的子类。
const obj = {
name: 'Sytus',
age: 18
}
(
...
{ obj } {/* 错误,无法显示 */}
)
- JSX的嵌入表达式:
...
this.state = {
first: 'Sytus',
last: 'Ramlethal'
}
...
(
<h2> { this.state.first + '' + this.state.last } </h2> {/* Sytus Ramlethal */}
)
- JSX绑定属性
<script type="text/babel">
function getSize(imgUrl, size){
return imgUrl + `param=${size}x${size}`
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
title: '标题',
imgUrl: 'http://172.22.4.2/',
active: false,
}
}
render() {
return (
<div>
{/* 绑定普通属性 */}
<h2 title={this.state.title}>我是标题</h2>
<img src={getSize(this.state.imgUrl, 200)}/>
{/* 绑定class */}
<div className='box'>我是一个DIV</div>
<div className={'box' + (this.state.active ? 'active' : '')}>我也是一个DIV</div>
{/* 绑定style */}
<div style={{ color: 'red', fontSize: '16px'}}>我是DIV</div>
{/* 第一个大括号意为将要开始编写JS代码,第二个大括号意为这是一个对象 */}
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector('#app'))
</script>
- JSX绑定事件:
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
msg: 'Hello'
}
this.btnClick = this.btnClick.bind(this)
}
render() {
return (
<div>
{/* 通过bind改变this指向 */}
{/* <button onClick={this.btnClick.bind(this)}>按钮</button> */}
<button onClick={this.btnClick}>按钮</button>
{/* 定义函数时使用箭头函数 */}
<button onClick={this.increment}>按钮</button>
{/* 直接传入箭头函数,在箭头函数中调用需要执行的函数(推荐) */}
<button onClick={() => {this.decrement()}}>按钮</button>
</div>
)
}
btnClick() {
console.log('按钮发生了点击。', this.state.msg)
}
// 箭头函数中永远不绑定this
increment = () => {
console.log(this.state.msg)
}
decrement() {
console.log(this.state.msg)
}
}
ReactDOM.render(<App />, document.querySelector('#app'))
</script>
绑定事件,传递参数:
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
arr: ['a', 'b', 'c']
}
this.btnClick = this.btnClick.bind(this)
}
render() {
return (
<div>
<button onClick={this.btnClick}>按钮</button>
<ul>
{
this.state.arr.map((item, index, arr) => {
return (<li onClick={(e) => {this.liClick(item, index, e)}}>{item}</li>)
})
}
</ul>
</div>
)
}
btnClick(e) {
console.log(e) // 能拿到event对象
}
liClick(item, index, e) {
console.log(item, index, e) // 拿到item,index和event对象
}
}
ReactDOM.render(<App />, document.querySelector('#app'))
</script>
React条件渲染
某些情况下,界面的内容会根据不同的情况显示不同的内容,或者决定是否渲染某部分内容。
原生判断
在React中,所有的条件判断都和普通的JS代码一致。
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isLogin: false
}
}
render() {
let welcome = null
let {isLogin} = this.state
if (isLogin) {
welcome = <h2>Hello World</h2>
} else {
welcome = <h2>Hello React</h2>
}
return (
<div>
{welcome}
<button>{this.state.isLogin ? '退出' : '登录'}</button>
<hr/>
<h2>{isLogin && 'Hello'}</h2>
<hr/>
<h2 style={{display: isLogin ? 'block' : 'none'}}>Hello</h2>
<hr/>
<h2 className={['title', (isActive ? 'active' : '')].join(' ')}>我是标题</h2>
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector('#app'))
</script>
通过classnames库进行条件添加类名
yarn add classnames
import classNames from 'classnames'
const errClass = 'error'
(
<h2 className={classNames('foo', 'bar')}>Hello World</h2>
// <h2 className='foo bar'></h2>
<h2 className={classNames({'active': true, 'bar': false}, 'title')}>Hello World</h2>
// <h2 className='active title'></h2>
<h2 className={classNames({'title', errClass})}>Hello World</h2>
// <h2 className='title error'>
)
React列表渲染
开发中我们会从服务器请求到大量的数据,数据会以列表的形式储存。
在React中,展示列表最多的方式是使用数组的map高阶函数。