React 开发通关指南:用 HTML 的思维写 JS🚀🚀

"在 JS 里写 HTML?这是什么操作?" 别慌!今天从最基础的 JSX 语法讲到 React 组件开发,用 "HTML+JS" 的混合思维带你入门,看完就能写出第一个 React 组件~

🔍 JSX本质:JavaScript的超能力扩展

JSX = JavaScript + XML,它允许我们在JavaScript中直接编写类似HTML的模板结构。它不是标准 JS,而是JS的扩展语法,所以需要 Babel 等工具解析后才能运行。

JSX 的核心规则:{}在 HTML 结构中嵌入 JS 代码

  • 字符串传递

    普通 HTML 里写字符串用引号,JSX 里如果想动态传字符串(或用 JS 变量拼字符串),可以这样:

    jsx 复制代码
    function App() {
      return <h1>Hello, 世界!</h1>; // 渲染出 <h1>Hello, 世界!</h1>
    }
  • 识别 JS 变量

    把 JS 变量的值嵌入 JSX 结构,直接用 {变量名} 。比如:

    jsx 复制代码
    const num = 10;
    function App() {
      return <p>这是一个数字:{num}</p>; // 显示 这是一个数字:10
    }
  • 函数 / 方法调用

    想在 JSX 里执行函数并展示结果,直接调用:

    jsx 复制代码
    function add(a, b) {
      return a + b;
    }
    function App() {
      return <p>计算结果:{add(3, 5)}</p>; // 显示 计算结果:8
    }
  • 使用 JS 对象

    比如给元素加样式对象,或者传递复杂数据:

    jsx 复制代码
    const styleObj = { color: 'red', fontSize: '20px' };
    function App() {
      return <p style={styleObj}>我是红色、20px 的文字</p>; 
    }

JSX 的 "小脾气":和 HTML 的区别

JSX 虽然长得像 HTML,但有几个细节不一样:

  • class → className :因为class是 JS 的关键字,所以 JSX 里用className定义类名;
  • style 用对象 :内联样式不能直接写字符串,要写成 JS 对象(键是驼峰命名,比如fontSize);
  • 标签必须闭合 :单标签(如<img><input>)必须写成<img />,双标签必须成对(如<div></div>)。
jsx 复制代码
// 正确的JSX写法
const element = (
  <div className="box" style={{ color: "red", fontSize: "16px" }}>
    <img src="logo.png" alt="logo" /> {/* 单标签必须闭合 */}
    <input type="text" />
  </div>
);

列表渲染:map 与 key 的 "默契配合"

开发中经常要渲染列表(比如数组转成一组 li ),用 map 遍历数组,同时必须加独一无二的 key (React 内部用来高效更新 DOM 的)。

示例:渲染 todo 列表

jsx 复制代码
const todos = ['吃饭', '睡觉', '打代码'];
function App() {
  return (
    <ul>
      {todos.map((todo, index) => (
        // 简单场景用 index 当 key(数据不变、无删除等操作时可用),复杂场景最好用唯一 ID
        <li key={index}>{todo}</li> 
      ))}
    </ul>
  );
}

为什么要 key ?React 靠 key 识别哪些元素新增、删除、变动,没 key 可能导致渲染异常、性能变差,面试也超爱考这点!

条件渲染:在 JSX 里写 "如果... 就..."

JSX 里不能直接写if语句,但可以用这 3 种方式实现条件渲染:

1. &&运算符:满足条件才显示

jsx 复制代码
const isLogin = true;

const element = (
  <div>
    <p>首页</p>
    {isLogin && <p>欢迎回来,用户!</p>} {/* isLogin为true时显示 */}
  </div>
);

2. ?:三元运算符:二选一

jsx 复制代码
const score = 85;

const element = (
  <div>
    {score >= 60 ? (
      <p>及格了!</p>
    ) : (
      <p>不及格,继续努力~</p>
    )}
  </div>
);

3. 自定义函数 + if

条件太多时,把逻辑抽到函数里,JSX 会更简洁:

jsx 复制代码
function getGrade(score) {
  if (score >= 90) return '优秀';
  if (score >= 60) return '合格';
  return '不合格';
}
function App() {
  const score = 85;
  return <p>你的评级:{getGrade(score)}</p>;
}

React 事件处理:让交互 "活" 起来

1.事件绑定:on + 事件名称 = {事件处理程序}

React 里绑定事件,语法是 on+事件名 (注意驼峰命名,比如 onClickonChange ),值是一个函数。示例:点击按钮提示消息

jsx 复制代码
function App() {
  function handleClick() {
    alert('按钮被点击啦!');
  }
  return <button onClick={handleClick}>点我</button>; 
  // 注意:是 onClick={handleClick} ,不是 onClick="handleClick()" ,后者是字符串,不会执行函数!
}

2.事件对象与自定义参数

  • 事件对象 e:React 会自动传递事件对象,比如阻止默认行为:

    jsx 复制代码
    function handleLinkClick(e) {
      e.preventDefault(); // 阻止链接默认跳转
      alert('链接被点击,但没跳转~');
    }
    function App() {
      return <a href="https://baidu.com" onClick={handleLinkClick}>点我试试</a>;
    }
  • 传递自定义参数:需要用箭头函数 "包裹",比如点击按钮传递 ID:

    jsx 复制代码
    function handleBtnClick(id) {
      alert(`你点击了 ID 为 ${id} 的按钮`);
    }
    function App() {
      return (
        <button onClick={() => handleBtnClick(10)}>
          点我传参
        </button>
      );
    }

    这里用箭头函数,是为了让 handleBtnClick 能拿到自定义参数 10 ,否则直接写 onClick={handleBtnClick(10)} 会导致函数直接执行(页面渲染时就触发),而不是点击时触发。

🧩 组件化:构建React应用的基石

组件是 React 的核心,首字母大写的函数,支持嵌套和复用

jsx 复制代码
// 这是一个组件,负责显示标题
function Title() {
  return <h1>我是页面标题组件</h1>;
}
// 这是另一个组件,用来组合其他组件
function App() {
  return (
    <div>
      <Title /> {/* 组件复用:这里渲染 Title 组件 */}
      <p>这是页面内容...</p>
    </div>
  );
}

组件首字母大写是约定,React 靠这个区分 "普通 HTML 标签" 和 "自定义组件",小写的会被当普通标签处理,这点面试常考!

组件渲染:自闭和与成对标签

组件渲染时,写法和 HTML 标签一样,可以是自闭和(/<组件名 /> )或成对( <组件名></组件名> )。比如:

jsx 复制代码
function Button() {
  return <button>我是按钮组件</button>;
}
function App() {
  return (
    <div>
      <Button /> {/* 自闭和写法 */}
      <Button></Button> {/* 成对写法,效果一样 */}
    </div>
  );
}

如果组件内部有子内容(比如 div 里套其他元素),就用成对写法;单纯复用组件,自闭和更简洁。

状态管理:useState 让组件 "有记忆"

React 组件默认是 "无状态" 的 ------ 每次渲染都会重置变量。useState是 React 提供的 "状态钩子",能让组件记住数据(状态),并在数据变化时自动重新渲染。

1. 基本用法:定义和使用状态

jsx 复制代码
import { useState } from 'react'; // 导入useState

function Counter() {
  // 定义状态:count是当前值,setCount是更新函数
  const [count, setCount] = useState(0); // 初始值为0

  return (
    <div>
      <p>点击了{count}次</p>
      <button onClick={() => setCount(count + 1)}>
        点我+1
      </button>
    </div>
  );
}
  • useState(0):初始化状态为 0,返回一个数组[当前值, 更新函数]
  • setCount(count + 1):更新状态(必须用更新函数,不能直接修改 count,因为状态是只读的);
  • 调用setCount后,组件会重新渲染,count会显示新值。

2. 状态是 "替换" 不是 "修改"

React 状态是只读的,更新对象 / 数组时,必须返回新的对象 / 数组,不能直接修改原数据:

jsx 复制代码
// 错误:直接修改状态(不会触发重新渲染)
const [user, setUser] = useState({ name: "张三" });
// ❌ user.name = "李四";

// 正确:返回新对象
setUser({ ...user, name: "李四" }); // 用扩展运算符复制旧数据,再修改

// 数组同理:不能直接push,要返回新数组
const [list, setList] = useState([1, 2, 3]);
setList([...list, 4]); // 正确:添加新元素并返回新数组

受控组件:表单输入的数据 "由 React 管"

在 React 中,表单元素(如 input、select)的值最好由状态管理,这样数据和视图能保持同步(类似 Vue 的v-model)。

jsx 复制代码
import { useState } from 'react';

function InputDemo() {
  // 用状态管理输入值
  const [text, setText] = useState("");

  return (
    <input
      type="text"
      value={text} // 输入框的值由状态控制
      onChange={(e) => setText(e.target.value)} // 输入变化时更新状态
    />
  );
}
  • value={text}:输入框显示状态text的值;
  • onChange:输入变化时,用setText更新状态;
  • 这样输入框的值始终和text一致,称为 "受控组件"。

🎯获取 DOM:useRef 让你直接 "摸" 到元素

有时候需要直接操作 DOM(如获取输入框焦点),可以用useRef钩子:

jsx 复制代码
import { useRef, useEffect } from 'react';

function RefDemo() {
  // 创建ref对象
  const inputRef = useRef(null);

  // 组件渲染后,让输入框自动聚焦
  useEffect(() => {
    inputRef.current.focus(); // current指向DOM元素
  }, []);

  return (
    <input
      type="text"
      ref={inputRef} // 绑定ref到输入框
    />
  );
}
  • useRef(null)创建一个 ref 对象,inputRef.current会指向绑定的 DOM 元素;
  • 适合处理焦点、获取画布上下文等需要直接操作 DOM 的场景。
相关推荐
蓝天白云下遛狗23 分钟前
goole chrome变更默认搜索引擎为百度
前端·chrome
come112341 小时前
Vue 响应式数据传递:ref、reactive 与 Provide/Inject 完全指南
前端·javascript·vue.js
musk12121 小时前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
万少2 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL2 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl023 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang3 小时前
前端如何实现电子签名
前端·javascript·html5
今天又在摸鱼3 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
蓝婷儿3 小时前
每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
前端
百锦再3 小时前
Vue中对象赋值问题:对象引用被保留,仅部分属性被覆盖
前端·javascript·vue.js·vue·web·reactive·ref