🐸 青蛙编程网
首页 / 前端 / React / 2. 环境搭建与 JSX

2. 环境搭建与 JSX

这是什么:JSX = 写在 JavaScript 里的 HTML 语法,让你能用熟悉的标签写法来描述页面结构。

为什么用:上一章的页面全是零散标签,正式组织代码前得先固定「起步姿势」。本章用公开 CDN 把 React 跑在一个普通 HTML 文件里——不用装任何东西。

如何用:本章先立「三行 CDN」的标准模板,跑一个计数器页面,再把 JSX 的五条规则背下来。

2.1 零工具起步:三行公开 CDN

免构建起步固定姿势:

  1. 引入三件套(公开 CDN,npmmirror 国内快):React 本体、ReactDOM 入口、Babel 编译器
  2. 页面里放一个空容器 <div id='root'>(React 接管把我们界面画进这里)
  3. 写一个 <script type='text/babel' data-presets='react'> 块——Babel 现场把这门 JS 里的 JSX 编译成浏览器认的代码

把下面的计数器整段贴进右侧「在线运行场」点运行,或存成 counter.html 双击打开:

<!DOCTYPE html>
<html lang='zh-CN'>
<head>
  <meta charset='utf-8'>
  <title>我的第一个 React 页面</title>
  <script src='https://registry.npmmirror.com/react/18.3.1/files/umd/react.production.min.js'></script>
  <script src='https://registry.npmmirror.com/react-dom/18.3.1/files/umd/react-dom.production.min.js'></script>
  <script src='https://registry.npmmirror.com/@babel/standalone/7.29.11/files/babel.min.js'></script>
</head>
<body>
  <div id='root'></div>

  <script type='text/babel' data-presets='react'>
    function App() {
      const [count, setCount] = React.useState(0)

      return (
        <div>
          <h1>我的第一个 React 页面</h1>
          <button onClick={() => setCount(count + 1)}>
            点了 {count} 次
          </button>
        </div>
      )
    }

    ReactDOM.createRoot(document.getElementById('root')).render(<App />)
  </script>
</body>
</html>

你会看到:蓝色标题下一颗按钮「点了 0 次」,每点一下数字加一。

几个容易迷惑的点:

  • data-presets='react':给 Babel 指明「帮我编译 JSX」,选的就是官方 @babel/preset-react
  • 免构建版没有 import:React、ReactDOM 是全局变量,钩子用 React.useState(...) 解构取
  • Babel 编译是实时的:只适合学习;正式项目用构建工具提前编译(见第 8 章末尾)

2.2 JSX 的五条规则

JSX = JavaScript 写在 HTML 外面。规则背下来就能写:

① 必须有一个根(外层用 <></> 或 div 包住)
② class 写成 className(class 是 JS 保留字)
③ JS 表达式用 { } 插入
④ 样式用对象:style={{ color: 'steelblue' }}
⑤ 标签必须闭合(<img />、<br />)

记忆口诀:{ } 里是 JS,其余是 HTML;class 改 className,错误一般出在闭合。

2.3 五条规则的对照示例页

五条规则在同一个页面里各就各(注释对号入座),整段可跑:

<!DOCTYPE html>
<html lang='zh-CN'>
<head>
  <meta charset='utf-8'>
  <title>JSX 五条规则</title>
  <script src='https://registry.npmmirror.com/react/18.3.1/files/umd/react.production.min.js'></script>
  <script src='https://registry.npmmirror.com/react-dom/18.3.1/files/umd/react-dom.production.min.js'></script>
  <script src='https://registry.npmmirror.com/@babel/standalone/7.29.11/files/babel.min.js'></script>
</head>
<body>
  <div id='root'></div>

  <script type='text/babel' data-presets='react'>
    function Greeting() {
      const name = '青蛙'
      const user = null

      return (
        // ① 唯一根 <div> · ② class 写成 className
        <div className='hello'>
          <h1 style={{ color: 'steelblue' }}>你好,{name}</h1>  {/* ③ 插值 · ④ 样式是对象套对象 */}
          <p>{user ? '有用户' : '游客'}</p>                {/* ③ 表达式就能算 */}
          <img
            style={{ width: '140px' }}
            src='https://images.pexels.com/photos/1370740/pexels-photo-1370740.jpeg?auto=compress&cs=tinysrgb&w=320'
            alt='青蛙'
          />  {/* ④ 内联样式要对象 · ⑤ 自闭合 <img /> */}
        </div>
      )
    }

    ReactDOM.createRoot(document.getElementById('root')).render(<Greeting />)
  </script>
</body>
</html>

你会看到:蓝色标题、灰色说明、正常显示的青蛙照片——注意 style={{ }} 是对象套对象,双大括号不是 Vue 的插值。

2.4 JSX 与 Vue 模板语法速查

你要做的 Vue React(JSX)
显示变量 {{ name }} {name}
属性绑定 :href="url" href={url}
条件块 v-if {ok ? <A/> : <B/>}
列表 v-for {arr.map(x => <li key={…}>)}
绑事件 @click="fn" onClick={fn}
双向 v-model 手动 value + onChange(下一章)

2.5 动手改

  1. 把 2.1 页面的按钮文案改成 {new Date().toLocaleDateString('zh-CN')}
  2. 在 2.3 页面加一行 <p className='tip'>,用 style={{ color: '#888' }} 给它灰色
  3. 故意写 <div>abc 不闭合,看 Babel 报什么错

2.6 小结

  • 起步三件套三行公开 CDN + <div id='root'> + text/babel 块,零工具直接跑
  • JSX 五规:唯一根 / className / { 表达式 } / 样式对象 / 必闭合
  • Vue 模板六件套的 React 对应写法已可对照转换

下一章:组件基础 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。