一文吃透 React 核心语法:JSX 从入门到实战进阶

141 阅读4分钟

一、JSX 是什么?React 开发者的 “可视化 UI 编辑器”

(一)一句话理解 JSX

JSX(JavaScript XML)是 React 独创的语法糖,允许在 JavaScript 中直接书写类似 HTML 的标签结构,让 UI 开发像拼积木一样直观。比如:

function Welcome() {
  return <h1>Hello, React世界!</h1>; // 这不是HTML,是能运行的JSX
}

(二)为什么 React 选择 JSX?三大核心优势

  • 读写友好:比纯 JS 的createElement链式调用更直观,一眼看清 UI 结构(想象一下用纯 JS 写嵌套 10 层的 DOM 有多酸爽)
  • 逻辑融合:在标签中直接嵌入 JS 表达式,数据驱动视图更丝滑({user.name}随手用,再也不用拼接字符串)
  • 类型安全:编译阶段就能捕获标签拼写、属性错误,减少运行时 BUG(妈妈再也不用担心我写错 class 啦~)

二、JSX 核心特性解析:从语法糖到运行时

(一)这些语法规则必须牢记!

  1. 标签闭合规则:所有标签必须正确闭合,单标签用/>结尾(别漏啦)
  2. 唯一根节点:组件返回值必须有单个顶层容器(加个<div>或者<>碎片标签)
  3. 属性命名规范:采用小驼峰命名(className代替classhtmlFor代替for

(二)JSX 中的 JS 表达式怎么用?

function App() {
  const isLogin = true;
  const user = { name: "稀土掘金用户" };
  const todoList = ["学JSX", "写组件", "搞实战"];

  return (
    <div>
      <h2>今天的目标:{todoList[0]}</h2> {/* 变量引用 */}
      {isLogin ? <Button>退出登录</Button> : <LoginForm />} {/* 条件渲染 */}
      <ul>
        {todoList.map((item, index) => ( // 列表渲染,记得加key!
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

(三)JSX 能直接运行吗?浏览器:这题我不会!

  • 答案:不能!需要 Babel 编译器翻译成React.createElement函数调用

  • 转换过程

    // 源码
    <h1 className="title">Hello, world</h1>
    
    // 编译后(React 17+)
    import { jsx as _jsx } from "react/jsx-runtime";
    _jsx("h1", { className: "title", children: "Hello, world" });
    
  • 小知识:React 17 之前必须手动引入React,现在编译器会自动处理啦~

三、JSX vs React.createElement:效率与性能的双重升级

(一)两种写法的本质区别

特性JSX 写法createElement 写法
可读性直观的 HTML 结构,层级一目了然嵌套的函数调用,容易看花眼
开发效率快速编写 UI,减少模板字符串拼接手动处理属性和子节点,容易出错
编译优化Babel 自动处理引号、转义等细节需手动处理属性类型和子节点格式

(二)实战代码对比:列表渲染的两种实现

// JSX写法(简洁派)
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
}

// createElement写法(底层派)
function TodoList({ todos }) {
  return React.createElement("ul", null,
    todos.map(todo => 
      React.createElement("li", { key: todo.id }, todo.title)
    )
  );
}

四、避坑指南:JSX 开发常见问题及解决方案

(一)表达式 vs 语句:这些坑别踩!

  • 错误示范:JSX 中不能直接写if语句

    {if (isShow) <div>显示内容</div>} //  报错!
    
  • 正确姿势:用三元表达式或逻辑与运算符

    {isShow ? <div>显示内容</div> : null} //  或者 {isShow && <div>显示内容</div>}
    

(二)样式怎么写?两种方案任你选

  1. 内联样式:使用驼峰命名的 JS 对象

    <div style={{ fontSize: "20px", color: "red" }}>红色大字体</div>
    
  2. 外部样式:通过className引用 CSS 类(推荐复杂样式)

    <div className="container">外部样式更清晰</div>
    

(三)key 值的正确用法:性能优化关键

  • 作用:帮助 React 识别列表项变化,避免不必要的重新渲染
  • 最佳实践:优先使用数据中的唯一标识(如 id),避免用 index(数据顺序变化时会出 bug!)

五、从入门到实战:完整组件开发示例

(一)组件代码:带交互的 TODO 列表

import { useState } from 'react';

function TodoApp() {
  const [todos, setTodos] = useState([
    { id: 1, title: "学习JSX核心语法" },
    { id: 2, title: "完成稀土掘金实战文章" }
  ]);

  const addTodo = (title) => {
    setTodos([...todos, { id: Date.now(), title }]);
  };

  return (
    <div className="todo-app">
      <h1>我的TODO列表</h1>
      <TodoInput onAdd={addTodo} />
      <TodoList todos={todos} />
    </div>
  );
}

// 子组件:输入框
function TodoInput({ onAdd }) {
  const [input, setInput] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    if (input.trim()) {
      onAdd(input);
      setInput("");
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="添加新任务"
      />
      <button>添加</button>
    </form>
  );
}

// 子组件:列表渲染
function TodoList({ todos }) {
  return (
    <ul className="todo-list">
      {todos.map(todo => (
        <TodoItem key={todo.id} todo={todo} />
      ))}
    </ul>
  );
}

// 子组件:单个任务项
function TodoItem({ todo }) {
  return (
    <li className="todo-item">
      {todo.title}
    </li>
  );
}

(二)代码亮点解析

  1. 组件化拆分:将功能拆分为父组件、输入框、列表、单个任务项,结构清晰易维护
  2. 状态管理:使用useState管理 TODO 数据,父子组件通过 props 通信
  3. JSX 应用:列表渲染、条件判断、样式绑定等常用场景一网打尽

六、总结:JSX 为什么是 React 开发的核心竞争力?

  • 声明式编程:用标签直接描述 UI,告别繁琐的 DOM 操作(写 UI 就像画画一样直观)

  • 学习曲线平滑:会 HTML 和 JS 就能快速上手,降低 React 入门门槛

  • 生态兼容性:Babel、TypeScript 等工具全面支持,适配现代前端开发流程

掌握 JSX 就像拿到了 React 开发的钥匙,无论是简单组件还是复杂应用,它都能让你的代码兼具可读性和高效性。现在就打开编辑器,用 JSX 写出你的第一个 React 组件吧~记得给列表项加上唯一 key 哦,这可是 React.diff 算法的小秘密~