React 入门第二步:搞懂 JSX 语法

勾勾的前端世界

共 6917字,需浏览 14分钟

 · 2021-08-26

JSX 是一个 JavaScript 的语法扩展,它不是字符串,也不是 HTML。


JSX 可以很好地描述 UI 交互的本质形式,它具有 JavaScript 的全部功能。JSX 可以生成 React “元素”。


基本使用


\src\index.js

import React from 'react'import ReactDom from 'react-dom'
// 看上去是 HTML,但是实际是JSX const title = <h1>Hello React</h1>// 调用 ReactDom.render方法,传入 jsx和节点对象ReactDom.render(title,document.getElementById('root'))


在使用 JSX 时,可以简单直接的按照 HTML 的规则来使用(你需要牢记它并不是 html ),那么有多行代码时,需要使用括号 () 包裹。

import React from 'react'import ReactDom from 'react-dom'
// 使用括号包裹jsx ,可以换行,代码更加整洁const title = ( <div> <h1>Hello React</h1> <span>嘿嘿嘿</span> </div>)
ReactDom.render(title,document.getElementById('root'))


设置 VS Code 编辑器,让 JSX 代码补全:

文件--首选项--设置--用户设置
在用户设置添加"emmet.includeLanguages": { "javascript":"javascriptreact"}


如下图所示:

 

JSX 表达式

前面说到 JSX 具有 JavaScript 的全部功能,而在具体使用时可以直接套用 HTML 的规则。换句话说,在 HTML 规则里,如何展现 JS 的能力呢?


先来一点简单的常常甜头,JSX 中的能够进行:

  • 动态显示数据 {}

  • 调用方法: 自定义 + 内置

  • 支持表达式, 支持三元表达式

  • 模板字符串


接下来,我们开始搞它:

import React from 'react';import ReactDOM from 'react-dom';
const name= '西岭老湿'
function sayHello () { return '大家好'}
const obj = { name: '刘备', age: 100}
const flag = true
// 请开始你的表演====const title = (<h2>嘿嘿</h2>) // JSX 本身也是可直接食用的值哟
const App = ( <div> {/* 注释在 jsx 中是这么个熊样子*/}
<p>name</p> {/* 这就鸳鸯(原样)展示了*/}
<p>{name}</p> {/* 动态获取变量数据 */}
<p>{sayHello()}</p> {/* 调用个函数违法吗? 不 */}
{/* 执行原生 JS 不合理吗? 合理 */} <p>{console.log('1111')}</p> <p>{Math.random()}</p> <p>{JSON.stringify(obj)}</p>
{/* 三元运算让你吃醋了? 没有 */} <p>{flag ? '登录的状态' :'执行登录'}</p>
{/* 模板字符下,字符串和变量结婚,可以吗? 可以 */} <p>{`hello, ${name}`}</p>
{/* JSX 也是可直接食用的值哟 */} <div>{title}</div> </div> )
ReactDOM.render(App,document.getElementById('root'));


  • JSX 本身就一个表达式

  • JSX 添加属性:

    字符串属性,直接使用双引号包裹

    动态属性,不用双引号,直接使用 {} class={xxx}

  • JSX 添加子元素

    JSX 只有一个父元素

  • 单标签必须闭合    


// 01 jsx 本身就是一个表达式const names = <h3>西岭老湿</h3>
// 02 添加属性const age =99
// 03 jsx 添加子元素(JSX只有一个父元素)

// 04 单标签必须闭合
// 组件functionApp() { return ( // 返回中只能有一个JSX 块 // <p></p> // 报错 <div> {/* jsx 本身就是一个表达式 */} {names}
{/* 添加属性 */} <page="age">用户年龄属性</p>{/* 字符串属性 */} <page={age}>用户年龄属性</p>{/* 动态属性 */}
{/* 单标签必须闭合 */} {/* <img > */}{/*报错*/} {/* 单标签正确写法 */} <img/>
</div> );}
exportdefault App;


最后,JSX 最好使用一个小括号 () 包裹。

 

事件绑定


事件处理函数和事件绑定

// 事件处理函数const event1 =function(){  alert('嘿嘿 React')}
functionApp (){ return ( <div> <h1>事件绑定</h1> {/* 事件名使用驼峰法命名、直接使用函数赋值,不是函数调用 */} <buttononClick={event1}>你点啊</button> </div> )}
exportdefault App


事件传参

因为事件绑定需要接收函数本身,作为事件处理,不能直接调用。

//事件传参const event1 =function(name,age){  alert(name)  alert(age)}
functionApp (){ return ( <div> <h1>事件绑定</h1> {/* 因为事件绑定需要接收函数本身,作为事件处理,不能直接调用 */} {/* 因此传参需要使用箭头函数返回事件处理函数,而不能是函数调用 */} <buttononClick={()=>{event1('西岭',16)}}>你点啊</button> <br/> {/* 或者使用 bind等其方式,将函数本身作为返回值传入 */}
<buttononClick={event1.bind(null,'嬴政',999)}>你再点一下试试</button>
{/* 再次强调 JSX 就是 JS 扩展,就是JS */} </div> )}
exportdefault App


因此传参需要使用箭头函数返回事件处理函数,而不能是函数调用,或者使用 bind 等其方式,将函数本身作为返回值传入。


再次强调 JSX 就是 JS 扩展,就是 JS。

 

事件对象传参

01 函数无传参:

 事件对象默认传入,因此直接在事件处理函数中形参接收即可。


02 箭头函数传参:

 因为事件对象有默认传入,而使用箭头函数时,则需要在箭头函数中传入后,再在箭头函数返回的函数中传入。


03 bind 等其方式:

 将函数本身作为返回值传入,事件对象默认会添加在最后一个参数中。

 无论有无参数传入,事件对象都不需要写,事件处理函数按顺序接收即可。

 

// 事件对象传参const event1 =function (ev) {  console.log(ev);}
functionApp() { return ( <div> <h1>事件绑定</h1> {/* 01 函数无传参 */} {/* 事件对象默认传入,因此直接在事件处理函数中形参接收即可 */} <buttononClick={event1}>点一下?</button> <br/>

{/* 02 箭头函数传参 因为事件对象有默认传入,而使用箭头函数时,则需要在箭头函数中传入后 再在箭头函数返回的函数中传入 */} <buttononClick={(ev) => { event1(ev,'西岭',16) }}>你点啊</button><br/>
{/* 03 bind 等其方式 将函数本身作为返回值传入,事件对象默认会添加在最后一个参数中 无论有无参数传入,事件对象都不需要写,事件处理函数按顺序接收即可 */} <buttononClick={event1.bind(null)}>你再点一下试试</button>
</div> )}
exportdefault App

 

列表渲染

JSX 默认会对数组进行结构,因此可以直接在 JSX 中展示数组的值。

const item1 = [1,3,5]
functionApp() { return ( <div> {/* JSX 默认会对数组进行结构 */} <h1>{item1}</h1> </div> )}
exportdefault App


同理,如果数组元素值也是 JSX,同样可以进行直接使用。

const item1 = [1,3,5]const item2 = [  <p>item1</p>,  <p>item1</p>,  <p>item1</p>]
functionApp() { return ( <div> {/* JSX 默认会对数组进行结构 */} <h1>{item1}</h1> {/* 数组值为 jsx 同样可以直接使用*/} <div> {item2} </div> </div> )}
exportdefault App


而在项目中,大部分获取到的数组元素是对象数据,要对其进行结构展示,就需要对数组进行循环操作后使用。

// 数组数据const arr = [  { id:1,name:'痴心绝对' },  { id:2,name:'像我这样的人' },  { id:3,name:'南山南' }]
// === 数据遍历 ===functionloops() { var a2 = [] // 循环遍历数据 for (var i =0; i < arr.length; i++) { // 将数组内容结构为JSX 数组 a2.push(<h1key={arr[i].id}>{arr[i].name}</h1>) } return a2}
functionApp() { return ( <div> {/* 调用遍历函数,获取 JSX 数组展示 */} {loops()} </div> )}
exportdefault App


这样的方式因为过于繁琐,并不推荐使用。


但是,基本思路是不变的,因为 JSX 可以自动结构数组结构,我们只需要将数据的数据遍历为 JSX 数据形式使用就可以了,因此,我们可以选择一种更为优雅的遍历方式map() 函数。


// 数组数据const arr = [  { id:1,name:'绝对痴心' },  { id:2,name:'像我这样帅的人' },  { id:3,name:'南山难' }]
functionApp() { return ( <div> {/* map 方法遍历数组 */} {arr.map(item=><h3>{item.id}--{item.name}</h3> )} </div> )}
exportdefault App


样式设置


内联样式

样式需要以对象形式展示:

//声明样式对象const styles = {  color:'red',  // 样式的属性名需要处理,要么  // font-size:'20px', // 直接使用报错  fontSize:'30px',// 转大写 √  'background-color':'pink'// 引号包裹 √}
functionApp (){ return ( <div> {/* 内联样式需要以对象形式展示 */} <h3style={{color:"red"}}>西岭老湿</h3> <pstyle={styles}>真的很帅</p> </div> )}
exportdefault App


外联样式

创建对应的 CSS 文件,使用模块化语法规则引入样式文件。


创建 CSS 文件 \src\App.css

body{  background-color: skyblue;  color: blue;}
.box{ font-size: 30px;}


\src\App.js

// 引入外联样式文件import './App.css'
function App (){ return ( <div> <h3>小蓝同学</h3> <pclassName="box">胖蓝</p> </div> )}
export default App


条件渲染

条件渲染就是函数调用。

import React from 'react'import ReactDom from 'react-dom'
var f = false
const fun1 = ()=>{ if(f){ return(<h1>哈哈哈哈</h1>) }else{ return(<h2>嘿嘿</h2>) }}const title = ( // 使用括号,可以换行,代码更加整洁 <div> {fun1()} </div>)
ReactDom.render(title,document.getElementById('root'))


推荐阅读:

React 入门第一步:环境搭建

这一把子彻底搞懂 setState 原理

面试官:“宝子,setState 是同步还是异步的呀?”

能替代 Vue 和 React 的框架,长什么样子?


恭喜你又在前端道路上进步了一点点。

点个“在看”和“”吧!

浏览 61
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报