学习 React 前,你必须掌握的 10 个 JavaScript 核心概念

如果你正计划入门 React.js,先稍等一下 —— 问问自己:“我的 JavaScript 基础真的扎实吗?”

 

React 并非写过几行 JS 就能直接上手的框架。它要求你清楚 JavaScript 的底层工作原理,尤其是那些看似简单、却支撑着整个 React 生态的核心概念。

 

下面就为大家详细拆解,每个 React 开发者在写出第一个 JSX 之前,必须掌握的 10 个 JavaScript 核心概念。

 

🔹 1. let、const 与 var

在 React 中,你会频繁声明变量。但如果使用不当,很容易引发难以排查的 bug。理解这三者的作用域规则、重声明限制以及暂时性死区,能帮你节省大量调试时间。

 

示例:三者的区别与应用场景

// var:函数级/全局作用域,存在变量提升,可重复声明

console.log(name); // 输出 undefined(变量提升但未赋值)

var name = "张三";

function testVar() {

  var name = "李四"; // 函数内重声明,不影响外部

  console.log(name); // 输出 李四

}

testVar();

console.log(name); // 输出 张三

// let:块级作用域,无变量提升,存在暂时性死区,不可重复声明

console.log(age); // 报错(暂时性死区,无法访问未初始化的let变量)

let age = 25;

if (true) {

  let age = 30; // 块内声明,不影响外部

  console.log(age); // 输出 30

}

console.log(age); // 输出 25

// const:块级作用域,必须初始化,不可重新赋值(引用类型内部可修改)

const PI = 3.14159;

PI = 3.14; // 报错(常量不可重新赋值)

const user = { name: "王五" };

user.name = "赵六"; // 可行(引用类型内部属性可修改)

console.log(user.name); // 输出 赵六

🔹 2. 变量提升(Hoisting)

React 组件本质就是 JavaScript 函数。但如果不理解变量提升,你常会遇到 “变量还没使用就报错” 的困惑 —— 这其实是提升机制在背后起作用。

 

示例:变量提升的表现与注意点

// 函数声明会整体提升,可在声明前调用

sayHello(); // 输出 Hello!

function sayHello() {

  console.log("Hello!");

}

// var声明的变量仅提升“声明”,不提升“赋值”

console.log(num); // 输出 undefined(声明提升,赋值未提升)

var num = 10;

console.log(num); // 输出 10

// let/const 无变量提升,存在暂时性死区

console.log(str); // 报错(无法访问未初始化的let变量)

let str = "test";

🔹 3. 闭包(Closures)

闭包不只是面试题考点 —— 它是 React Hooks(尤其是useState、useEffect)和事件处理的核心动力。没有闭包,React 的状态保存与行为逻辑几乎无法实现。

 

示例:闭包在 React 中的实际应用

// 闭包基础:内部函数访问外部函数变量,变量不会被销毁

function createCounter() {

  let count = 0; // 外部函数变量,被内部函数引用

  return function () {

    count++;

    return count;

  };

}

const counter = createCounter();

console.log(counter()); // 输出 1

console.log(counter()); // 输出 2(count状态被保留)

// React中闭包的典型场景:useState依赖闭包保存状态

import { useState } from "react";

function CounterComponent() {

  const [count, setCount] = useState(0);

  

  // 事件处理函数通过闭包访问count状态

  const handleIncrement = () => {

    setCount(count + 1); // 此处能访问count,正是闭包的作用

  };

  

  return <button onclick="{handleIncrement}">计数:{count}</button>;

}

🔹 4. 回调函数(Callback Functions)

React 严重依赖回调函数 —— 从事件处理(onClick)到副作用管理(useEffect)都离不开它。掌握 “如何传递函数”“如何延迟执行” 以及 “如何避免回调地狱”,是 React 开发的基础。

 

示例:React 中的回调函数与优化

// 1. 事件处理中的回调函数

function Button() {

  // 回调函数:点击时才执行

  const handleClick = () =&gt; {

    console.log("按钮被点击");

  };

  // onClick接收回调函数,不立即执行

  return <button onclick="{handleClick}">点击我</button>;

}

// 2. 避免回调地狱:用async/await优化异步请求

async function getUserOrders() {

  try {

    // 第一步:获取用户信息

    const userRes = await fetch("/api/user");

    const user = await userRes.json();

    // 第二步:获取用户订单(无需嵌套)

    const ordersRes = await fetch(`/api/user/${user.id}/orders`);

    const orders = await ordersRes.json();

    console.log("用户订单:", orders);

  } catch (error) {

    console.error("请求失败:", error);

  }

}

🔹 5. Promise 与 Async/Await

在 React 中,调用 API 获取数据是日常操作(如用fetch或国内常用的axios)。掌握 Promise 与 async/await,能让你写出不阻塞浏览器的异步代码,避免页面 “卡死”。

 

示例:结合 axios 的异步数据请求(国内常用场景)

import { useState, useEffect } from "react";

import axios from "axios"; // 国内常用的HTTP库

function DataComponent() {

  const [userData, setUserData] = useState(null);

  const [loading, setLoading] = useState(false);

  // 用async/await封装异步请求

  const fetchUserData = async () =&gt; {

    setLoading(true);

    try {

      // 示例:请求掘金用户接口(需处理跨域,实际项目需后端代理)

      const res = await axios.get("https://api.juejin.cn/user_api/v1/user/get");

      setUserData(res.data.data); // 赋值返回的用户数据

    } catch (error) {

      console.error("数据获取失败:", error);

    } finally {

      setLoading(false); // 无论成功失败,都结束加载状态

    }

  };

  // 组件挂载时执行请求

  useEffect(() =&gt; {

    fetchUserData();

  }, []);

  // 加载状态与数据展示

  return loading ? (

    <div>加载中...</div>

  ) : (

    <div>欢迎,{userData?.user_name || "游客"}</div>

  );

}

🔹 6. 数组方法(map、filter、reduce)

React 开发围绕数组展开:用map渲染列表、用filter筛选数据、用reduce统计信息 —— 这些方法能让你的 UI 逻辑更简洁高效。

 

示例:React 中数组方法的高频用法

import { useState } from "react";

function UserList() {

  const [users, setUsers] = useState([

    { id: 1, name: "张三", age: 16, isVip: false },

    { id: 2, name: "李四", age: 20, isVip: true },

    { id: 3, name: "王五", age: 22, isVip: true },

  ]);

  // 1. map:渲染列表(React必用,需加key)

  const userItems = users.map((user) =&gt; (

    <li key="{user.id}">

      {user.name}({user.age}岁){user.isVip ? "[VIP]" : ""}

    </li>

  ));

  // 2. filter:筛选VIP用户

  const vipUsers = users.filter((user) =&gt; user.isVip);

  // 3. reduce:计算用户平均年龄

  const avgAge = users.reduce((sum, user) =&gt; sum + user.age, 0) / users.length;

  return (

    <div>

      <h3>所有用户</h3>

      <ul>{userItems}</ul>

      <p>VIP用户数:{vipUsers.length}</p>

      <p>平均年龄:{avgAge.toFixed(1)}</p>

    </div>

  );

}

🔹 7. 解构(Destructuring)

在 React 中,从props或state中提取值时,解构能让代码更简洁易读 —— 尤其在函数组件中,几乎是 “标配” 写法。

 

示例:React 中的解构应用

// 1. 解构props(最常用场景)

// 未解构:代码冗长

function Greeting(props) {

  return <h1>你好,{props.name}!年龄:{props.age}</h1>;

}

// 解构:简洁清晰

function Greeting({ name, age }) {

  return <h1>你好,{name}!年龄:{age}</h1>;

}

// 2. 解构state

import { useState } from "react";

function Profile() {

  const [user, setUser] = useState({

    name: "张三",

    address: "北京",

    phone: "138****1234",

  });

  // 从user中解构需要的属性

  const { name, address } = user;

  return <div>{name} 住在 {address}</div>;

}

// 3. 数组解构(配合useState)

const [count, setCount] = useState(0); // 解构useState返回的数组

🔹 8. 扩展与剩余运算符(Spread & Rest Operators)

这两个运算符在 React 中高频出现:处理props传递、更新状态、合并对象等场景都能用到,极大简化了数据操作逻辑。

 

示例:React 中的运算符应用

// 1. 扩展运算符(...):传递所有props

function Parent() {

  const user = { name: "张三", age: 25, gender: "男" };

  // 用...将user的所有属性传递给Child,无需逐个写props

  return <child {...user} />;

}

function Child({ name, age, gender }) {

  return <div>{name},{age}岁,{gender}</div>;

}

// 2. 扩展运算符:更新React状态(不可直接修改原状态)

import { useState } from "react";

function Profile() {

  const [profile, setProfile] = useState({

    name: "张三",

    age: 25,

  });

  // 只更新age,保留其他属性(正确写法)

  const updateAge = () =&gt; {

    setProfile({ ...profile, age: 26 }); // ...profile复制原有属性

  };

  return (

    <div>

      <p>年龄:{profile.age}</p>

      <button onclick="{updateAge}">增加年龄</button>

    </div>

  );

}

// 3. 剩余运算符(...):收集多个参数

function sum(...numbers) {

  // numbers是一个数组,包含所有传入的参数

  return numbers.reduce((total, num) =&gt; total + num, 0);

}

console.log(sum(1, 2, 3)); // 输出 6

🔹 9. 真值与假值(Truthy and Falsy Values)

React 的条件渲染完全依赖 JavaScript 的真值 / 假值判断。理解 “哪些值被视为 true,哪些被视为 false”,能帮你避免 UI 渲染异常(如空数组显示 “有数据”)。

 

示例:条件渲染中的真值 / 假值应用

// JavaScript中的假值(仅6个):false、0、""、null、undefined、NaN

// 其他值均为真值(包括 "0"、{}、[]、true 等)

import { useState } from "react";

function LoginStatus() {

  const [user, setUser] = useState(null); // 未登录时为null(假值)

  // 条件1:用户登录(user为真值)显示欢迎语

  // 条件2:用户未登录(user为假值)显示登录按钮

  return user ? (

    <div>欢迎,{user.name}!</div>

  ) : (

    <button onclick="{()" => setUser({ name: "张三" })}&gt;登录</button>

  );

}

// 注意:空数组[]是真值,需判断长度

function List({ data }) {

  // 错误:data为[]时,if(data)为true,会显示“有数据”

  // if (data) return <div>有数据</div>;

  

  // 正确:判断数组长度

  if (data.length &gt; 0) {

    return <div>有数据:{data.map(item =&gt; <p key="{item.id}">{item.name}</p>)}</div>;

  }

  return <div>无数据</div>;

}

🔹 10. DOM 与事件(基础)

React 虽然封装了 DOM(虚拟 DOM),但仍需与原生 DOM 交互。理解基础的 DOM 操作和原生事件,能帮你搞懂 React 合成事件的底层逻辑,避免 “事件绑定失效” 等问题。

 

示例:原生 DOM 与 React 合成事件对比

// 1. 原生DOM操作(理解原理)

// HTML:<button id="nativeBtn">原生按钮</button>

const nativeBtn = document.getElementById("nativeBtn");

nativeBtn.addEventListener("click", () =&gt; {

  console.log("原生按钮被点击");

});

// 2. React合成事件(开发常用)

import { useState } from "react";

function ReactButton() {

  const [count, setCount] = useState(0);

  // React合成事件:onClick(驼峰命名,区别于原生onclick)

  const handleClick = (e) =&gt; {

    setCount(count + 1);

    // e是React合成事件对象,可通过e.nativeEvent获取原生事件

    console.log("原生事件对象:", e.nativeEvent);

  };

  // React自动管理事件解绑,无需手动移除

  return <button onclick="{handleClick}">点击次数:{count}</button>;

}

// 3. 阻止默认行为(如表单提交)

function Form() {

  const handleSubmit = (e) =&gt; {

    // 阻止表单默认提交(原生与React写法一致)

    e.preventDefault();

    console.log("表单已处理,不刷新页面");

  };

  return (

    <form onSubmit="{handleSubmit}">

      <button type="submit">提交表单</button>

    </form>

  );

}

🧠 为什么这些概念如此重要?

理论上,即使不掌握这些概念,你也能 “拼凑” 出一个 React 应用 —— 但代价是:频繁困惑、卡壳,只能从 Stack Overflow(或国内的掘金、优快云)复制代码,却不懂背后的逻辑。

 

这些概念是 React 开发的 “地基”:它们不仅帮你写出代码,更能让你理解 “React 为什么要这么设计”(比如 Hooks 依赖闭包、状态不可直接修改)。

 

🎥 加餐:视频学习资源

如果你偏好 “视觉 + 场景化” 学习,不必局限于国外平台(如 YouTube)。国内的技术平台(如 B 站、掘金视频)有大量优质教程,搜索 “React 前置 JS 知识点”“React 基础 JS 概念”,就能找到适合国内开发者的入门内容,帮你更清晰地建立知识体系。

 

✨ 最后想说的话

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值