使用 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><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 />}</>
}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 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>
        </>
    )
}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>
}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><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>
    )
}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>登录模块
                <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>
        </>
    )
}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>
}export default function Form() {
    return <h1 className="title">登录模块</h1>
}因为 JSX 最终会被编译转化为 JavaScript 语法,而 JSX 中的属性也会变成 JavaScript 对象中的键值对。我们也知道一个对象 Object 的键名不能使用一些特殊符号。
