React框架详解:从入门到精通(详细版)

Hi,我是前端人类学! React 是由 Facebook 开发并维护的一个用于构建用户界面的 JavaScript 库。自2013年5月首次发布以来,React 因其高效性、灵活性和强大的生态系统而广受欢迎。React 不仅可以用于构建 Web 应用程序,还可以通过 React Native 构建移动应用程序。本文将详细介绍 React 的核心概念、生命周期方法、最新特性以及最佳实践,帮助读者全面掌握这一强大的前端工具。

一、官方网站

React 的官方网站是 react.docschina.org/。在这里,你可以找到官方文档、教程、API 参考以及社区资源。

二、安装React

2.1 使用 Create React App

Create React App 是一个官方支持的脚手架工具,可以帮助你快速搭建一个 React 应用程序。以下是安装步骤:

  1. 确保已安装 Node.js :首先确保你的机器上已经安装了 Node.js。你可以通过运行以下命令来检查:

    sh 复制代码
    node -v
    npm -v
  2. 安装 Create React App :打开终端或命令行工具,运行以下命令来全局安装 Create React App:

    sh 复制代码
    npx create-react-app my-app
  3. 进入项目目录

    sh 复制代码
    cd my-app
  4. 启动开发服务器

    sh 复制代码
    npm start

    这将启动一个本地开发服务器,并在浏览器中打开 http://localhost:3000,你将看到一个默认的 React 应用程序。

2.2 手动安装

如果你不想使用 Create React App,也可以手动安装 React 和相关依赖。以下是步骤:

  1. 初始化项目

    sh 复制代码
    mkdir my-app
    cd my-app
    npm init -y
  2. 安装 React 和 React DOM

    sh 复制代码
    npm install react react-dom
  3. 创建入口文件 :在项目根目录下创建一个 index.html 文件:

    html 复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>React App</title>
    </head>
    <body>
     <div id="root"></div>
     <script src="./index.js"></script>
    </body>
    </html>
  4. 创建主 JavaScript 文件 :在项目根目录下创建一个 index.js 文件:

    javascript 复制代码
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    const App = () => {
     return <h1>Hello, React!</h1>;
    };
    
    ReactDOM.render(<App />, document.getElementById('root'));
  5. 启动开发服务器 :你可以使用 webpack 或其他模块打包工具来启动开发服务器。这里以 webpack 为例:

    sh 复制代码
    npm install --save-dev webpack webpack-cli babel-loader @babel/core @babel/preset-env @babel/preset-react
  6. 配置 Webpack :在项目根目录下创建一个 webpack.config.js 文件:

    javascript 复制代码
    const path = require('path');
    
    module.exports = {
      entry: './index.js',
      output: {
    	filename: 'bundle.js',
    	path: path.resolve(__dirname, 'dist')
      },
      module: {
    	rules: [
      	  {
        	test: /\.js$/,
        	exclude: /node_modules/,
        	use: {
          	  loader: 'babel-loader'
            }
      	  }
    	]
      }
    };
  7. 配置 Babel :在项目根目录下创建一个 .babelrc 文件:

    json 复制代码
    {
      "presets": ["@babel/preset-env", "@babel/preset-react"]
    }
  8. 添加启动脚本 :在 package.json 中添加一个启动脚本:

    json 复制代码
    "scripts": {
      "start": "webpack serve --open"
    }
  9. 启动开发服务器

    bash 复制代码
    npm start

三、React 核心概念

3.1 组件化

React 的核心理念之一是组件化。组件化意味着将复杂的用户界面分解为多个小的、可重用的组件。每个组件负责渲染一部分 UI,并且可以拥有自己的逻辑和状态。组件之间通过属性(Props)进行通信,形成树状结构。

  • 函数组件 :使用简单的函数定义,接收输入参数(Props),返回要渲染的元素。从 React 16.8 开始,函数组件可以通过 Hooks 使用状态和其他功能。

    javascript 复制代码
    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
  • 类组件 :继承自 React.Component 类,可以通过 this.statethis.props 访问状态和属性。

    javascript 复制代码
    class Welcome extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }

3.2 JSX

JSX 是一种扩展语法,允许在 JavaScript 中编写类似于 HTML 的标记语言。实际上,JSX 会被编译成普通的 JavaScript 函数调用,通常是 React.createElement()

  • 基本语法

    javascript 复制代码
    const element = <h1>Hello, world!</h1>;
  • 嵌入式表达

    javascript 复制代码
    const name = 'Josh Perez';
    const element = <h1>Hello, {name}</h1>;

3.3 虚拟DOM

虚拟 DOM 是 React 内部使用的轻量级 DOM 树副本。当组件的状态或属性发生变化时,React 会先在虚拟 DOM 上进行更改,然后通过高效的算法计算出最小的更新操作,最后将这些操作应用到真实的 DOM 上,从而减少不必要的 DOM 操作,提高性能。

3.4 Props 和 State

  • Props :属性(Properties)是从父组件传递给子组件的数据。Props 是不可变的,子组件不能修改它接收到的 Props。

    javascript 复制代码
    function ChildComponent(props) {
      return <div>{props.message}</div>;
    }
    
    function ParentComponent() {
      return <ChildComponent message="Hello from parent!" />;
    }
  • State :状态是组件内部用来存储数据的对象。它可以随时改变,当状态变化时,React 会自动重新渲染组件以反映最新的状态。

    javascript 复制代码
    class Counter extends React.Component {
      constructor(props) {
      super(props);
      this.state = { count: 0 };
    }
    
    increment = () => {
      this.setState({ count: this.state.count + 1 });
    }
    
    render() {
      return (
        <div>
          <p>Count: {this.state.count}</p>
          <button onClick={this.increment}>Increment</button>
        </div>
      )
     }
    }

四、生命周期方法

React 组件的生命周期可以分为三个主要阶段:挂载、更新和卸载。每个阶段都有相应的生命周期方法,这些方法可以在特定的时间点执行特定的操作。

  • 挂载阶段
    • constructor(props):构造函数,在组件实例创建时调用。
    • static getDerivedStateFromProps(nextProps, prevState):静态方法,在每次渲染之前调用,用于根据新的 Props 更新 State。
    • render():渲染方法,返回要显示的 UI。
    • componentDidMount():组件挂载后调用,通常用于发起网络请求或设置定时器。
  • 更新阶段
    • static getDerivedStateFromProps(nextProps, prevState):在每次渲染前调用,用于根据新的 Props 更新 State。
    • shouldComponentUpdate(nextProps, nextState):决定组件是否需要重新渲染,默认返回 true。
    • render():重新渲染组件。
    • getSnapshotBeforeUpdate(prevProps, prevState):在最近一次渲染输出(提交到 DOM 节点)之前调用,可以捕获 DOM 变化前的信息。
    • componentDidUpdate(prevProps, prevState, snapshot):组件更新后调用,通常用于更新 DOM 或发起网络请求。
  • 卸载阶段
    • componentWillUnmount():组件卸载前调用,用于清理定时器、取消网络请求等操作。

五、新特性介绍

5.1 Hooks

Hooks 是 React 16.8 版本引入的新特性,允许在不编写类的情况下使用状态和其他 React 功能。Hooks 主要包括以下几种:

  • useState :用于声明状态变量。

    javascript 复制代码
    import React, { useState } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
             Click me
          </button>
        </div>
      )
    }
  • useEffect :用于执行副作用操作,如数据获取、订阅或手动更改 DOM。

    javascript 复制代码
    import React, { useState, useEffect } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        document.title = `You clicked ${count} times`;
      })
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
             Click me
          </button>
    	</div>
      )
    }
  • useContext :用于访问 React 的上下文(Context)。

    javascript 复制代码
    import React, { useContext } from 'react';
    
    const ThemeContext = React.createContext('light');
    
    function ThemedButton() {
      const theme = useContext(ThemeContext);
      return <button style={{ background: theme }}>Themed Button</button>;
    }

5.2 Context API

Context API 提供了一种在组件树中传递数据的方式,而无需手动地通过 Props 逐层传递。这对于大型应用中的全局状态管理非常有用。

  • 创建 Context

    javascript 复制代码
    const MyContext = React.createContext(defaultValue);
  • 提供者(Provider)

    javascript 复制代码
    <MyContext.Provider value={value}>
      {/* 子组件 */}
    </MyContext.Provider>
  • 消费者(Consumer)

    javascript 复制代码
    <MyContext.Consumer>
      {value => /* 基于 context 值的 UI */}
    </MyContext.Consumer>
  • useContext Hook

    javascript 复制代码
    const value = useContext(MyContext);

六、状态管理

在复杂的应用中,状态管理变得尤为重要。React 提供了几种不同的状态管理解决方案,包括但不限于:

6.1 Redux

Redux 是一个用于管理应用状态的库,常与 React 一起使用。它通过一个全局的 store 来集中管理应用的状态。

  • 安装 Redux

    bash 复制代码
    npm install redux react-redux
  • 创建 Store

    javascript 复制代码
    import { createStore } from 'redux';
    
    const initialState = {
      counter: 0
    };
    
    const reducer = (state = initialState, action) => {
    switch (action.type) {
      case 'INCREMENT':
        return { ...state, counter: state.counter + 1 };
      case 'DECREMENT':
        return { ...state, counter: state.counter - 1 };
      default:
        return state;
      }
    }
    
    const store = createStore(reducer)
  • 连接组件

    javascript 复制代码
    import React from 'react';
    import { useSelector, useDispatch } from 'react-redux';
    
    function Counter() {
      const counter = useSelector(state => state.counter);
      const dispatch = useDispatch();
    
      return (
        <div>
          <p>Counter: {counter}</p>
          <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
          <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
        </div>
      )
    }
    
    export default Counter

6.2 Mobx

MobX 是一个简单、透明的状态管理库,它通过可观察对象和反应式视图来管理状态。

  • 安装 MobX

    bash 复制代码
    npm install mobx mobx-react
  • 创建 Store

    javascript 复制代码
    import { makeAutoObservable } from 'mobx';
    
    class CounterStore {
      counter = 0;
    
      constructor() {
        makeAutoObservable(this);
      }
    
      increment = () => {
        this.counter += 1;
      }
    
      decrement = () => {
        this.counter -= 1;
      }
    }
    
    const counterStore = new CounterStore()
  • 连接组件

    javascript 复制代码
    import React from 'react';
    import { observer } from 'mobx-react';
    import { counterStore } from './stores/CounterStore';
    
    const Counter = observer(() => {
      return (
        <div>
          <p>Counter: {counterStore.counter}</p>
          <button onClick={counterStore.increment}>Increment</button>
          <button onClick={counterStore.decrement}>Decrement</button>
        </div>
      )
    })
    
    export default Counter

6.3 React Context API

React 的 Context API 也可以用于状态管理,特别是在中小型应用中。虽然它不如 Redux 和 MobX 强大,但对于简单的状态管理需求已经足够。

  • 创建 Context

    javascript 复制代码
    import React, { createContext, useState } from 'react';
    
    const CounterContext = createContext();
    
    const CounterProvider = ({ children }) => {
      const [counter, setCounter] = useState(0);
    
      const increment = () => setCounter(counter + 1);
      const decrement = () => setCounter(counter - 1);
    
      return (
        <CounterContext.Provider value={{ counter, increment, decrement }}>
          {children}
        </CounterContext.Provider>
      )
    }
    
    export { CounterContext, CounterProvider }
  • 使用 Context

    javascript 复制代码
    import React, { useContext } from 'react';
    import { CounterContext } from './CounterContext';
    
    const Counter = () => {
      const { counter, increment, decrement } = useContext(CounterContext);
    
      return (
        <div>
          <p>Counter: {counter}</p>
          <button onClick={increment}>Increment</button>
          <button onClick={decrement}>Decrement</button>
        </div>
      )
    }
    
    export default Counter

七、最佳实践

7.1 组件划分

保持组件的小型化和单一职责原则,有助于提高代码的可读性和可维护性。小型组件更容易测试和复用。

7.2 代码复用

  • 高阶组件(HOCs) :高阶组件是一个函数,接受一个组件并返回一个新的组件。HOCs 可以用于封装共享逻辑。

    javascript 复制代码
    function withLoading(WrappedComponent) {
      return function EnhancedComponent(props) {
      if (props.isLoading) {
        return <div>Loading...</div>;
      }
        return <WrappedComponent {...props} />;
      }
    }
  • Render Props :Render Props 是一种在 React 组件之间共享代码的技术,通过将函数作为 props 传递来实现。

    javascript 复制代码
    class MouseTracker extends React.Component {
      // ...
    
      render() {
        return this.props.render(this.state.mousePosition);
      }
    }
    
    function App() {
      return (
        <MouseTracker render={mousePosition => (
          <h1>The mouse position is {mousePosition.x}, {mousePosition.y}</h1>
        )} />
      )
    }

7.3 性能优化

  • React.memo :用于函数组件,如果 Props 没有变化,则跳过渲染。

    javascript 复制代码
    const MyComponent = React.memo(function MyComponent(props) {
      /* 渲染使用 props 的 UI */
    })
  • useMemo :用于缓存计算结果,避免重复计算。

    javascript 复制代码
    function MyComponent(props) {
      const memoizedValue = useMemo(() => computeExpensiveValue(props), [props]);
      // ...
    }

7.4 错误边界

错误边界是一种 React 组件,可以捕获并处理其子组件树中任何地方抛出的 JavaScript 错误。错误边界可以防止整个应用崩溃。

  • 定义边界错误

    javascript 复制代码
    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = { hasError: false };
      }
    
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
    
      componentDidCatch(error, errorInfo) {
        logErrorToMyService(error, errorInfo);
      }
    
      render() {
        if (this.state.hasError) {
          return <h1>Something went wrong.</h1>;
        }
    
        return this.props.children; 
      }
    }
  • 使用边界错误

    javascript 复制代码
    <ErrorBoundary>
      <MyWidget />
    </ErrorBoundary>

掌握其核心概念和最佳实践对于构建高效、可维护的应用至关重要。希望本文能帮助读者全面理解和运用 React,构建出优秀的用户界面。

相关推荐
牛仔只喝牛奶8 小时前
多端跨端技术选型:小程序 + H5 + App 的两栈拆分落地
react native·react.js
wear工程师11 小时前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
wanghowie13 小时前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
csj5014 小时前
前端基础之《React(11)—state声明式》
前端·react.js
张元清15 小时前
React useLocalStorage Hook:SSR 安全的持久化状态(2026)
javascript·react.js
析数塔15 小时前
2026前端框架深度解析:React Compiler、Angular Zoneless、Vue 3.5重写游戏规则
前端·vue.js·react.js
杖雍皓15 小时前
没有服务器如何构建现代 Web 应用:平台选型与组合策略
运维·服务器·前端·react.js·github·netlify·vercel
sun_weitao16 小时前
微前端框架之qiankun 怎么用?vue3+vite+qiankun 和 react + qiankun
前端·react.js·前端框架
名字还没想好☜1 天前
React useEffect 依赖数组踩坑:闭包陷阱与清理函数
前端·javascript·react.js·react·useeffect
我是大卫1 天前
【图】React源码解析-第四部分:事件与跨层传递
react.js·源码