1147 字
6 分钟
01.JSX核心语法
2025-03-28

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书写规范#

  1. JSX的顶层只能有一个根元素;

  2. 为了方便阅读,我们通常在JSX的外层包裹一个小括号();

  3. 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高阶函数。

在对一个数组中的数据进行处理时,过滤内容我们使用filter函数,截取数组我们只用slice函数。

01.JSX核心语法
https://sytusramlethal.github.io/posts/01jsx核心语法/
作者
Sytus Ramlethal
发布于
2025-03-28
许可协议
CC BY-NC-SA 4.0