2025 年了,你还在畏惧 JSX 吗?5 个真实场景 + 完整源码,带你彻底掌握 React 最核心语法

96 阅读3分钟

在 React 世界里,JSX 就是我们的母语。它不是字符串,也不是 HTML,而是一套能够在 JavaScript 中直接书写 UI 结构的语法糖。很多初学者一看到“在 JS 里写 HTML”就本能排斥,但真正用熟之后,你会发现:这才是现代前端最自然、最高效的开发方式。

今天用 5 个逐步递进的真实业务场景 + 完整可运行代码,带你从“看不懂 JSX”到“爱上 JSX”。

一、JSX 本质:只是 createElement 的语法糖

jsx

const element = <h2>JSX 是 React 中用于描述用户界面的语法扩展</h2>;

// 等价于
const element2 = createElement(
  'h2',
  null,
  'JSX 是 React 中用于描述用户界面的语法扩展'
);

所有 JSX 最终都会被 Babel 编译成 React.createElement 调用。记住这一点,你就永远不会被它的“怪模样”吓到。

二、为什么 React 敢把“模板”彻底干掉?

Vue 仍然保留 template,React 却把 UI 完全交给 JS,原因只有一句话:

当 UI 足够复杂时,逻辑必然会入侵模板,而模板语言表达复杂逻辑的能力极弱。

jsx

// Vue template 要写成这样(v-for + v-if + 三元表达式嵌套)
<div v-if="todos.length">
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      {{ todo.done ? '[已完成]' : '[未完成]' }} {{ todo.title }}
    </li>
  </ul>
</div>

// React JSX:直接用 JS 该怎么写就怎么写
{todos.length > 0 ? (
  <ul>
    {todos.map(todo => (
      <li key={todo.id}>
        {todo.done ? '[已完成]' : '[未完成]'} {todo.title}
      </li>
    ))}
  </ul>
) : (
  <div className="empty">暂无代办事项</div>
)}

你感受一下哪个更清晰、更自由?

三、状态驱动 UI:useState + JSX 的黄金组合

jsx

function App() {
  const [name, setName] = useState("Vue");
  const [todos] = useState([
    { id: 1, title: "学习 React", done: false },
    { id: 2, title: "学习 Vue", done: true }
  ]);
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  // 2 秒后自动切换,展示响应式更新
  setTimeout(() => setName("React"), 2000);

  return (
    <>
      <h1>
        Hello <span className="title">{name}</span>
      </h1>

      {todos.length > 0 ? (
        <ul className="todo-list">
          {todos.map(todo => (
            <li key={todo.id} className={todo.done ? 'done' : ''}>
              {todo.title}
            </li>
          ))}
        </ul>
      ) : (
        <div>暂无代办事项</div>
      )}

      <div className="login-status">
        {isLoggedIn ? "已登录" : "未登录"}
      </div>

      <button onClick={() => setIsLoggedIn(!isLoggedIn)}>
        {isLoggedIn ? "退出登录" : "登录"}
      </button>
    </>
  );
}

这就是 React 的核心哲学:数据变 → 组件函数重新执行 → 生成新的 UI 描述 → React 智能 Diff → 最小化更新 DOM。

四、组件才是王道:用 JSX 像搭积木一样构建页面

传统前端以“页面”为单位,React 以“组件”为单位。来看一个完整的掘金首页布局:

jsx

// 头部组件
function JuejinHeader() {
  return (
    <header className="juejin-header">
      <h1>稀土掘金</h1>
      <nav>
        <a href="/">首页</a>
        <a href="/tags">标签</a>
        <a href="/search">搜索</a>
      </nav>
    </header>
  );
}

// 文章列表组件
const Articles = () => {
  return (
    <main className="articles">
      <article>2025 年前端趋势分析</article>
      <article>你还在手写 useEffect 依赖数组?</article>
      {/* 省略 20 篇 */}
    </main>
  );
};

// 侧边栏签到组件
const Checkin = () => {
  return (
    <div className="checkin-widget">
      <h3>每日签到</h3>
      <button>立即签到 +5 矿石</button>
    </div>
  );
};

// 热门文章组件
const HotArticles = () => {
  return (
    <div className="hot-articles">
      <h3>24 小时热门</h3>
      <ol>
        <li>React 19 发布了!</li>
        <li>TypeScript 5.6 性能提升 60%</li>
      </ol>
    </div>
  );
};

// 根组件:组合一切
function App() {
  return (
    <div className="juejin-homepage">
      <JuejinHeader />
      
      <div className="container">
        <section className="main-content">
          <Articles />
        </section>
        
        <aside className="sidebar">
          <Checkin />
          <HotArticles />
        </aside>
      </div>
    </div>
  );
}

export default App;

这就是组件化开发的魅力:每个组件职责单一、独立可复用、组合方式无限。

五、为什么说“函数就是组件”?

在 React 里,只要一个函数返回了 JSX,它就是一个组件。原因非常纯粹:

  • JS 本身就是函数式语言
  • 函数天然具备闭包、参数、返回值
  • 配合 Hooks,函数组件的能力已经全面超越 class 组件

jsx

// 2025 年,你应该这样写组件
const Button = ({ onClick, children, variant = "primary" }) => {
  return (
    <button className={`btn btn-${variant}`} onClick={onClick}>
      {children}
    </button>
  );
};

// 使用
<Button onClick={handleLogin} variant="danger">
  退出登录
</Button>

六、JSX 不是“怪语法”,而是未来

很多人初学 React 时最大的心理障碍就是 JSX,但真正用 3 个月后,99% 的人再也不想回到模板语法。

因为:

  • 逻辑和视图终于在同一个地方,不用再来回切换文件
  • 所有 JS 能力(三元、map、filter、async/await)都可以直接用在 UI 中
  • 组件就是函数,组合性、复用性、测试性都达到了极致

当你写出第一个 200 行的 JSX 组件,发现它居然如此清晰易读时,你就会明白 Facebook 当年为什么敢 All in JSX。