reactjs(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

2. ReactJS 的核心概念

ReactJS 是由 Facebook(现 Meta)开发的 JavaScript 库,专注于构建用户界面。它以组件化、单向数据流和高效渲染著称,成为现代前端开发的主流工具。对于编程初学者而言,理解其核心概念是掌握 ReactJS 的关键。

2.1 组件化:构建界面的乐高积木

ReactJS 的核心思想是“一切皆组件”。组件是独立且可复用的代码块,类似于乐高积木——你可以将复杂界面拆解为多个小组件,再通过组合这些组件构建完整的页面。例如,一个电商网站的购物车功能可以拆分为“商品列表组件”“商品卡片组件”和“结算按钮组件”。

组件的优势

  • 可维护性:修改一个组件不会影响其他部分;
  • 复用性:相同逻辑的组件可在不同页面重复使用;
  • 协作友好:团队成员可独立开发不同组件。

示例:一个简单的按钮组件

function MyButton({ label }) {  
  return <button>{label}</button>;  
}  
// 使用组件  
<MyButton label="点击我" />  

2.2 状态(State)与属性(Props)

ReactJS 中,状态(State)和属性(Props)是数据流动的核心。

状态(State):组件的“记忆”

状态是组件内部管理的数据,例如用户输入的表单内容或计时器的当前时间。当状态变化时,组件会自动重新渲染。

属性(Props):父组件传递的“指令”

Props 是父组件传递给子组件的数据,用于控制子组件的行为。例如,父组件可以传递一个 isDisabled prop 来禁用子按钮。

对比表格
| 特征 | State | Props |
|--------------|---------------------------|--------------------------|
| 来源 | 组件内部定义 | 由父组件传递 |
| 可修改性 | 可通过 setState 或 Hooks 修改 | 只读,不可直接修改 |
| 用途 | 管理组件自身状态 | 接收外部数据或指令 |

示例:使用 State 和 Props

// 父组件  
function Parent() {  
  return <Child message="Hello" />;  
}  

// 子组件  
function Child({ message }) {  
  const [count, setCount] = useState(0);  
  return (  
    <div>  
      <p>{message}</p>  
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>  
    </div>  
  );  
}  

2.3 虚拟 DOM 与高效渲染

ReactJS 通过虚拟 DOM(Virtual DOM)优化渲染性能。当数据变化时,ReactJS 会先在内存中生成新的虚拟 DOM 树,通过对比新旧树的差异,再仅更新实际需要变化的 DOM 节点,避免全页面重绘。

比喻
虚拟 DOM 就像一张地图,程序员看到的是地图的变化,而实际城市(真实 DOM)只更新必要的区域。

示例:对比直接操作 DOM 与 ReactJS

// 直接操作 DOM(低效)  
document.getElementById("counter").innerHTML = count;  

// ReactJS 方式(高效)  
function Counter() {  
  const [count, setCount] = useState(0);  
  return <div>{count}</div>;  
}  

3. 函数组件与类组件:选择适合的开发模式

ReactJS 支持函数组件和类组件两种开发模式,但函数组件结合 Hooks 是当前的主流实践。

3.1 函数组件:简洁与现代

函数组件是轻量级的函数,接收 Props 并返回 JSX。通过 React Hooks(如 useStateuseEffect)可管理状态和副作用。

示例:函数组件与 Hooks

function Timer() {  
  const [time, setTime] = useState(new Date().toLocaleTimeString());  

  useEffect(() => {  
    const interval = setInterval(() => {  
      setTime(new Date().toLocaleTimeString());  
    }, 1000);  
    return () => clearInterval(interval); // 清理副作用  
  }, []);  

  return <div>当前时间:{time}</div>;  
}  

3.2 类组件:兼容与传统

类组件基于 ES6 类语法,需继承 React.Component 并实现 render() 方法。状态通过 this.statethis.setState() 管理。

示例:类组件实现计时器

class Timer extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { time: new Date().toLocaleTimeString() };  
  }  

  componentDidMount() {  
    this.interval = setInterval(() => {  
      this.setState({ time: new Date().toLocaleTimeString() });  
    }, 1000);  
  }  

  componentWillUnmount() {  
    clearInterval(this.interval);  
  }  

  render() {  
    return <div>当前时间:{this.state.time}</div>;  
  }  
}  

3.3 为什么推荐函数组件?

  • 代码更简洁:无需 classthis 关键字;
  • Hooks 扩展性:通过 useStateuseEffect 等 Hook 可灵活管理复杂逻辑;
  • 未来趋势:React 团队持续优化 Hooks,新特性优先支持函数组件。

4. 组件间通信:从 Props 到 Context API

在复杂应用中,组件需要相互通信。ReactJS 提供了多种方式实现数据传递,包括 Props 针对传递、Refs 和 Context API。

4.1 Props 针对传递:父子组件直接通信

父子组件通过 Props 传递数据,但深层嵌套可能导致 Props 链式传递(Prop Drilling)。

示例:父到子的 Props 传递

function Parent() {  
  return <Child message="来自父组件的问候" />;  
}  

function Child({ message }) {  
  return <p>{message}</p>;  
}  

4.2 Context API:跨越层级共享数据

当多个组件需要访问同一数据(如用户认证信息)时,使用 Context API 可避免 Props 链式传递。

示例:使用 Context API 管理主题

// 创建 Context  
const ThemeContext = React.createContext();  

// 提供者组件  
function ThemeProvider({ children }) {  
  const [theme, setTheme] = useState("light");  
  return (  
    <ThemeContext.Provider value={{ theme, setTheme }}>  
      {children}  
    </ThemeContext.Provider>  
  );  
}  

// 消费 Context  
function ThemedButton() {  
  const { theme } = useContext(ThemeContext);  
  return <button style={{ backgroundColor: theme === "dark" ? "black" : "white" }}>按钮</button>;  
}  

4.3 Refs:直接访问 DOM 或组件实例

Refs 允许直接操作 DOM 元素或 React 组件实例,常用于处理表单输入或焦点控制。

示例:通过 Ref 获取输入框值

function Login() {  
  const inputRef = useRef();  

  const handleSubmit = () => {  
    console.log("用户名:", inputRef.current.value);  
  };  

  return (  
    <div>  
      <input ref={inputRef} type="text" placeholder="用户名" />  
      <button onClick={handleSubmit}>登录</button>  
    </div>  
  );  
}  

5. 高阶组件(HOC)与渲染 props:复用逻辑的高级技巧

ReactJS 的灵活性体现在其复用逻辑的能力上,高阶组件(HOC)和渲染 props 是两种常见模式。

5.1 高阶组件:组件工厂

HOC 是一个函数,接收组件作为参数并返回一个新组件,常用于封装公共逻辑(如权限验证或数据获取)。

示例:使用 HOC 添加加载状态

function withLoading(WrappedComponent) {  
  return function WithLoading(props) {  
    const [isLoading, setLoading] = useState(true);  

    useEffect(() => {  
      setTimeout(() => setLoading(false), 1000); // 模拟异步请求  
    }, []);  

    return isLoading ? <div>加载中...</div> : <WrappedComponent {...props} />;  
  };  
}  

// 使用 HOC  
const LoadingPost = withLoading(Post);  

5.2 渲染 props:通过函数传递逻辑

渲染 props 通过 Props 传递函数,允许父组件控制子组件的渲染逻辑。

示例:使用渲染 props 传递主题

function ThemeProvider({ children }) {  
  const [theme, setTheme] = useState("light");  
  return children({ theme, toggleTheme: () => setTheme(theme === "light" ? "dark" : "light") });  
}  

// 使用渲染 props  
<ThemeProvider>  
  {({ theme, toggleTheme }) => (  
    <div>  
      <button onClick={toggleTheme}>切换主题</button>  
      <p style={{ color: theme === "dark" ? "white" : "black" }}>当前主题:{theme}</p>  
    </div>  
  )}  
</ThemeProvider>  

6. ReactJS 生态系统:从路由到状态管理

ReactJS 本身轻量,但其生态系统提供了丰富的工具链,如路由库 React Router、状态管理库 Redux 等。

6.1 React Router:构建单页应用(SPA)

React Router 是 React 的路由解决方案,支持动态路由和页面导航。

示例:定义基础路由

import { BrowserRouter as Router, Route, Link } from "react-router-dom";  

function App() {  
  return (  
    <Router>  
      <nav>  
        <Link to="/">首页</Link>  
        <Link to="/about">关于</Link>  
      </nav>  

      <Route path="/" exact component={Home} />  
      <Route path="/about" component={About} />  
    </Router>  
  );  
}  

6.2 状态管理:Redux 或 React Query

对于复杂应用,单组件状态可能不足以管理全局数据。Redux 通过集中式状态树和 reducer 管理状态,而 React Query 则专注于 API 数据获取和缓存。

示例:使用 React Query 获取数据

function UserList() {  
  const { data, error, isLoading } = useQuery("users", fetchUsers);  

  if (isLoading) return <div>加载中...</div>;  
  if (error) return <div>加载失败</div>;  

  return (  
    <ul>  
      {data.map(user => (  
        <li key={user.id}>{user.name}</li>  
      ))}  
    </ul>  
  );  
}  

7. ReactJS 的最佳实践与性能优化

掌握核心概念后,开发者还需关注代码质量和性能优化。

7.1 关键优化技巧

  • 避免不必要的渲染:使用 React.memouseMemo 缓存组件或计算结果;
  • 优化列表渲染:为列表项添加 key 属性,帮助 React 识别变化;
  • 代码分割:使用动态导入(import())实现代码按需加载。

示例:使用 React.memo 缓存组件

const MemoizedComponent = React.memo(function Component({ data }) {  
  // 仅在 data 变化时重新渲染  
  return <div>{data}</div>;  
});  

7.2 开发工具:React Developer Tools

Chrome 的 React Developer Tools 插件可查看组件树、状态和 Props,是调试的必备工具。


8. 结论:为什么选择 ReactJS?

ReactJS 通过组件化、虚拟 DOM 和丰富的生态,成为构建现代前端应用的首选工具。无论是初学者还是中级开发者,掌握其核心概念后,可以快速构建高效、可维护的用户界面。随着 Hooks 和 TypeScript 的普及,ReactJS 的学习曲线持续降低,而其社区的支持和更新速度也确保了其长期生命力。

开始你的 ReactJS 之旅吧!

最新发布