使用 JSX 书写标签语言
JSX (JavaScript XML) 是由 Facebook 开发的。它是一种 JavaScript 语法扩展,可以让你在 JavaScript 文件中书写类似 HTML 的标签。
JSX 并不是原生的 JavaScript 语法,需要通过 Babel 等工具编译成标准的 JavaScript 代码。
为什么 React 将标签和渲染逻辑耦合在一起
网页是构建在 HTML、CSS 和 JavaScript 之上的。多年以来,web 开发者都是将网页内容存放在 HTML 中,样式放在 CSS 中,而逻辑则放在 JavaScript 中。
<body>
<div id="login">
<h1>登录模块</h1>
<button onclick="login()">登录</button>
</div>
<div id="register">
<h1>注册模块</h1>
<button onclick="register()">注册</button>
</div>
</body>
<script>
const type = 'login' // 当前为登录模块
if (type === 'login') {
document.getElementById('login').style.display = 'block'
document.getElementById('register').style.display = 'none'
}
if (type === 'register') {
document.getElementById('register').style.display = 'block'
document.getElementById('login').style.display = 'none'
}
function login() {
console.log('login')
}
function register() {
console.log('register')
}
</script>
但随着 Web 的交互性越来越强,页面上的内容基本上都是由逻辑去控制。这也是为什么在 React 中,标签和逻辑耦合在一起的原因。
import Register from './Register'
import Login from './Login'
export default function Form() {
const type = 'login' // 当前为登录模块
return <>{type === 'login' ? <Login /> : <Register />}</>
}
export default function Login() {
const submit = () => {
console.log('login')
}
return (
<>
<h1>登录模块</h1>
<button onClick={submit}>登录</button>
</>
)
}
export default function Register() {
const submit = () => {
console.log('register')
}
return (
<>
<h1>注册模块</h1>
<button onClick={submit}>注册</button>
</>
)
}
这种模式更适合组件化,方便维护和复用。例如要改登录的逻辑代码,只需要到 Login.jsx
文件修改即可,无需关心其他代码,也不会因为改动而影响其他文件。
JSX
!== React
JSX and React 是相互独立的东西。但它们经常一起使用,但你可以单独使用它们中的任意一个,JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。
import { useState } from 'react' // 在 React 库中使用 useState 钩子
export default function Form() {
const [text] = useState('Hello world!')
// 使用 JSX 语法
return <h1>{text}</h1>
}
JSX
!== HTML
JSX
并不是 HTML
,JSX 语法更加严格并且相比 HTML 有更多的规则。所以你将 HTML 的代码直接复制到 JSX 中,可能无法正常工作。
这里将举例一个错误的案例,假设你现在有一段可在 Web 中运行的 HTML 标签。
<div id="login">
<h1>登录模块
<button >登录</button>
</div>
<div id="register">
<h1>注册模块
<button>注册</button>
</div>
现在将上面的 HTML 转化为 JSX 代码,直接拷贝到 React 组件中。
export default function Form() {
return (
<div id="login">
<h1>登录模块
<button>登录</button>
</div>
<div id="register">
<h1>注册模块
<button>注册</button>
</div>
)
}
其实这样是不能工作的!
首先是 JSX
只允许返回一个根元素,如果你不想在标签中增加一个额外的 <div>
,可以用 <>
和 </>
元素来代替。
export default function Form() {
return (
<>
<div id="login">
<h1>登录模块
<button>登录</button>
</div>
<div id="register">
<h1>注册模块
<button>注册</button>
</div>
</>
)
}
其次是标签必须要闭合
export default function Form() {
return (
<>
<div id="login">
<h1>登录模块</h1>
<button>登录</button>
</div>
<div id="register">
<h1>注册模块</h1>
<button>注册</button>
</div>
</>
)
}
最后是标签的属性必须使用驼峰写法,而且一部分关键字不能使用,如 class
必须写成 className
。
export default function Form() {
return <h1 className="title">登录模块</h1>
}
因为 JSX
最终会被编译转化为 JavaScript
语法,而 JSX
中的属性也会变成 JavaScript
对象中的键值对。我们也知道一个对象 Object
的键名不能使用一些特殊符号。