JSX 基本语法
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 单标签必须闭合
// 组件
function App() {
return (
// 返回中只能有一个 JSX 块
// <p></p> // 报错
<div>
{/* jsx 本身就是一个表达式 */}
{names}
{/* 添加属性 */}
<p age="age">用户年龄属性</p> {/* 字符串属性 */}
<p age={age}>用户年龄属性</p> {/* 动态属性 */}
{/* 单标签必须闭合 */}
{/* <img > */} {/* 报错*/}
{/* 单标签 正确写法 */}
<img />
</div>
);
}
export default App;
最后,JSX 最好使用一个小括号() 包裹;
事件绑定
事件处理函数和事件绑定
// 事件处理函数
const event1 = function(){
alert('嘿嘿 React')
}
function App (){
return (
<div>
<h1>事件绑定</h1>
{/* 事件名使用驼峰法命名、直接使用函数赋值,不是函数调用 */}
<button onClick={event1}>你点啊</button>
</div>
)
}
export default App
事件传参
因为事件绑定需要接收函数本身,作为事件处理,不能直接调用
// 事件传参
const event1 = function(name,age){
alert(name)
alert(age)
}
function App (){
return (
<div>
<h1>事件绑定</h1>
{/* 因为事件绑定需要接收函数本身,作为事件处理,不能直接调用 */}
{/* 因此传参需要使用箭头函数返回事件处理 函数,而不能是函数调用 */}
<button onClick={()=>{event1('西岭',16)}}>你点啊</button>
<br />
{/* 或者使用 bind 等其方式,将函数本身作为返回值传入 */}
<button onClick={event1.bind(null,'嬴政',999)}>你再点一下试试</button>
{/* 再次强调 JSX 就是 JS 扩展,就是 JS */}
</div>
)
}
export default App
因此传参需要使用箭头函数返回事件处理函数,而不能是函数调用,或者使用 bind 等其方式,将函数本身作为返回值传入;
再次强调 JSX 就是 JS 扩展,就是 JS
事件对象传参
01 函数无传参:
事件对象默认传入,因此直接在事件处理函数中形参接收即可。
02 箭头函数传参:
因为事件对象有默认传入,而使用箭头函数时,则需要在箭头函数中传入后,再在箭头函数返回的函数中传入。
03 bind 等其方式:
将函数本身作为返回值传入,事件对象默认会添加在最后一个参数中。
无论有无参数传入,事件对象都不需要写,事件处理函数按顺序接收即可
// 事件对象传参
const event1 = function (ev) {
console.log(ev);
}
function App() {
return (
<div>
<h1>事件绑定</h1>
{/* 01 函数无传参 */}
{/* 事件对象默认传入,因此直接在事件处理函数中形参接收即可 */}
<button onClick={event1}>点一下?</button> <br />
{/* 02 箭头函数传参
因为事件对象有默认传入,而使用箭头函数时,则需要在箭头函数中传入后
再在箭头函数返回的函数中传入 */}
<button onClick={(ev) => { event1(ev,'西岭', 16) }}>你点啊</button> <br />
{/* 03 bind 等其方式
将函数本身作为返回值传入,事件对象默认会添加在最后一个参数中
无论有无参数传入,事件对象都不需要写,事件处理函数按顺序接收即可 */}
<button onClick={event1.bind(null)}>你再点一下试试</button>
</div>
)
}
export default App
列表渲染
JSX 默认会对数组进行结构,因此可以直接在 JSX 中展示数组的值。
const item1 = [1,3,5]
function App() {
return (
<div>
{/* JSX 默认会对数组进行结构 */}
<h1>{item1}</h1>
</div>
)
}
export default App
同理,如果数组元素值也是 JSX,同样可以进行直接使用。
const item1 = [1,3,5]
const item2 = [
<p>item1</p>,
<p>item1</p>,
<p>item1</p>
]
function App() {
return (
<div>
{/* JSX 默认会对数组进行结构 */}
<h1>{item1}</h1>
{/* 数组值为 jsx 同样可以直接使用 */}
<div>
{item2}
</div>
</div>
)
}
export default App
而在项目中,大部分获取到的数组元素是对象数据,要对其进行结构展示,就需要对数组进行循环操作后使用。
// 数组数据
const arr = [
{ id: 1, name: '痴心绝对' },
{ id: 2, name: '像我这样的人' },
{ id: 3, name: '南山南' }
]
// === 数据遍历 ===
function loops() {
var a2 = []
// 循环遍历数据
for (var i = 0; i < arr.length; i++) {
// 将数组内容结构为 JSX 数组
a2.push(<h1 key={arr[i].id}>{arr[i].name}</h1>)
}
return a2
}
function App() {
return (
<div>
{/* 调用遍历函数,获取 JSX 数组展示 */}
{loops()}
</div>
)
}
export default App
这样的方式因为过于繁琐,并不推荐使用;
但是,基本思路是不变的,因为 JSX 可以自动结构数组结构,我们只需要将数据的数据遍历为 JSX 数据形式使用就可以了,因此,我们可以选择一种更为优雅的遍历方式 map() 函数;
// 数组数据
const arr = [
{ id: 1, name: '绝对痴心' },
{ id: 2, name: '像我这样帅的人' },
{ id: 3, name: '南山难' }
]
function App() {
return (
<div>
{/* map 方法遍历数组 */}
{arr.map(item=><h3>{item.id}--{item.name}</h3> )}
</div>
)
}
export default App
样式设置
内联样式
样式需要以对象形式展示:
// 声明样式对象
const styles = {
color:'red',
// 样式的属性名需要处理,要么
// font-size:'20px', // 直接使用报错
fontSize:'30px', // 转大写 √
'background-color':'pink' // 引号包裹 √
}
function App (){
return (
<div>
{/* 内联样式需要以对象形式展示 */}
<h3 style={{color:"red"}} >西岭老湿</h3>
<p style={styles}>真的很帅</p>
</div>
)
}
export default 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>
<p className="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'))
总结
JSX 是 React 非常重要的组成部分,我们在编程中最重要的就是 UI 渲染的结果呈现,而 JSX 其实就是 JS 版的 HTML ,或者你也可以直接理解为我们在使用 JavaScript 写 HTML 。