Ant Design Pro快速入门——React框架

纯前端菜鸡,只有一些HTML、CSS和JavaScript的基础,最近配合的前端跑路了,想用Ant Design Pro来快速搭建一套中后台来管理数据,只能自己上了,主要自己也想试试水,从后端的视角看前端,整体偏向于实战。

📘 React 笔记

一、React 核心概念

定位:Facebook 开源的 JavaScript UI 框架
特性

  • ⚡ 虚拟 DOM 实现高性能渲染
  • 🧩 组件化开发模式
  • 📦 声明式编程范式
  • 🌐 跨平台能力(Web/React Native)

二、环境搭建指南

两种创建方式对比

方式 命令 特点
全局安装 cnpm i -g create-react-app 长期维护多个项目时适用
推荐 npx npx create-react-app my-app 零安装,始终使用最新版本

完整流程

# 1. 创建项目
npx create-react-app my-react-learn

# 2. 进入目录
cd my-react-learn

# 3. 启动开发服务器
npm start

# 4. 访问地址
http://localhost:3000

三、项目结构解析

核心目录架构

my-react-learn/
├── 📁 node_modules/    # 存放所有项目的依赖包,由npm或yarn自动生成,包含了项目运行所需的所有第三方库和模块
├── 📁 public/          # 存放静态文件,Webpack不会对这个目录中的文件进行处理,而是直接复制到输出目录中
│   ├── 🖼️ index.html   # HTML模板文件,React会将组件渲染到<div id="root"></div>中
│   └── 📜 manifest.json # Web应用清单文件,用于定义应用的名称、图标等元数据
├── 📁 src/             # 源码目录
│   ├── 🎨 App.css      # 组件样式
│   ├── ⚛️ App.js       # 根组件
│   └── 🚀 index.js     # 应用入口
├── 📄 .gitignore       # 版本控制排除
├── 📦 package.json     # 项目元数据
└── 🔒 package-lock.json # 依赖锁文件

关键文件说明

文件 作用 开发关注度
index.html 页面模板 ★★☆
index.js React 渲染入口 ★★★
App.js 主组件逻辑 ★★★
reportWebVitals.js 性能监测工具 ★☆☆

四、组件

组件是React的核心构建块,它们是React应用的基本单元,负责渲染和交互。

1. 组件类型对比

特性 函数组件 类组件
语法 箭头函数/普通函数 ES6 class
状态管理 Hooks (useState) this.state
生命周期 useEffect 生命周期方法
代码量 简洁 相对冗长
推荐度 ✅ 主流 ⚠️ 旧项目维护

2. 函数组件示例

// 🆕 现代推荐写法
import React from 'react';

const Welcome = ({ name }) => (
  <div className="greeting">
    <h1>Hello, {name}!</h1>
    <small>Welcome to React World</small>
  </div>
);

export default Welcome;

如果你通过 crate-react-app 创建了一个 React 应用,在/pulic/index.html中有<div id="root"></div>一段,我们将其称为“根”DOM节点,React DOM可以确保浏览器DOM节点与React元素完全匹配。React元素是不可变的,当元素被创建后,无法改变其内容或属性,更新界面的唯一办法是创建一个新的元素,然后将它传递给ReactDOM.render()方法。

3. Props

Props是组件的输入参数,用于从父组件向子组件传递数据,Props是只读的,子组件不能修改他们。

import React from "react";

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

<Welcome name="大毛" />

如果我想修改示例中的name属性,则会抛出Cannot assign to read only property 'name' of object异常。也可以将函数作为props传递给子组件,这样子组件就可以调用父组件的函数来与父组件进行通信。

4. 状态管理(State)

类组件可以拥有状态,它是组件数据的私有部分,与 Props(由父组件传递的只读数据)不同,State 是组件私有的、可变的,它的变化会触发组件的重新渲染。

import react from "react";
import reactDOM from "react-dom/client";

class Hello extends react.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  incrment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count:{this.state.count}</p>
        <button onClick={this.incrment}>incrment</button>
      </div>
    );
  }
}

export default Hello;

虽然State是类组件的状态,但是你可以通过 React Hook在函数组件中使用状态,最常用的就是 useState:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  // 推荐函数式更新
  const increment = () => setCount(prev => prev + 1);
  
  return (
    <div className="counter">
      <p>Current: {count}</p>
      <button onClick={increment}>
        Increment
      </button>
    </div>
  );
}

5. 事件处理

React的事件处理与DOM元素类似,但绑定方式如下:

import react from "react";
import reactDOM from "react-dom/client";

//创建一个简单的React组件
function Hello() {
  return (
    <div>
      <h1>Hello, React!</h1>
      <button onClick={() => alert("Hello, React!")}>打招呼</button>
    </div>
  );
}

const root = reactDOM.createRoot(document.getElementById("root"));

root.render(<Hello />);

如果使用class语法来定义组件,事件处理器会成为类的一个方法,如:

import React from "react";

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isToggleOn: true,
    };

    // 事件绑定,只有这样this才能在回调函数中使用,否则会出现 undefined
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(id) {
    this.setState((prevState) => ({
      isToggleOn: !prevState.isToggleOn,
    }));
    alert(id);
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>
          {this.state.isToggleOn ? "开" : "关"}
        </button>
      </div>
    );
  }
}

export default Toggle;

//index.js
import react from "react";
import reactDOM from "react-dom/client";
import Toggle from "./toggle.js";
//创建一个简单的React组件

const root = reactDOM.createRoot(document.getElementById("root"));

root.render(<Toggle />);

6. 生命周期

组件的生命周期主要ming 生命周期,包括:

  1. Mounting(挂载):组件插入到DOM中时触发,包括初始化props和state。
  2. Updating(更新):组件收到新的props或state时触发,包括更新UI。
  3. Unmounting(卸载):组件从DOM中移除时触发,包括清理资源。

生命周期钩子函数:

挂载

  • constructor():在组件创建时调用,通常用于初始化state和props。
  • getDerivedStateFromProps(props, state):在render方法之前调用,并且在初始挂载及后续更新时都会被调用。
  • reander():class组件中唯一必须实现的方法,用于渲染组件。
  • componentDidMount():在组件挂载后调用,通常用于数据请求或DOM操作。

更新

  • getDerivedStateFromProps:在render方法之前调用,并且在初始挂载及后续更新时都会被调用。
  • shouldComponentUpdate:在组件收到新的props或state时调用,返回一个布尔值,用于判断是否需要更新组件。
  • render:组件收到新的props或state时调用。
  • getSnapshotBeforeUpdate:在最近一次渲染输出之前调用。
  • componentDidUpdate:在组件更新后调用,通常用于数据请求或DOM操作。

卸载

  • componentWillUnmount:在组件从DOM中移除时调用,通常用于清理资源。

下面是一个示例:

import react from "react";
import reactDOM from "react-dom/client";

class Hello extends react.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    console.log("调用了constructor");
  }

  static getDerivedStateFromProps(props, state) {
    console.log("调用了getDerivedStateFromProps");
    return null;
  }

  componentDidMount() {
    console.log("调用了componentDidMount");
  }

  componentDidUpdate() {
    console.log("调用了componentDidUpdate");
  }

  componentWillUnmount() {
    console.log("调用了componentWillUnmount");
  }

  incrment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    console.log("调用了render");
    return (
      <div>
        <p>Count:{this.state.count}</p>
        <button onClick={this.incrment}>incrment</button>
      </div>
    );
  }
}

export default Hello;

//输出如下:
//调用了constructor
//调用了getDerivedStateFromProps
//调用了render
//调用了componentDidMount
//此时点击increment按钮,输出:
//调用了getDerivedStateFromProps
//调用了render
//调用了componentDidUpdate

五、 其他用法

列表

import react from "react";
import reactDOM from "react-dom/client";

//创建一个简单的React组件
function Hello() {
  const numbers = [1, 2, 3, 4, 5];
  const listItems = numbers.map((number) => (
    <li key={number.toString()}>{number}</li>
  ));
  return listItems;
}

const root = reactDOM.createRoot(document.getElementById("root"));

root.render(
  <ul>
    <Hello />
  </ul>
);

export default Hello;

表单

在HMTL中,像input、textarea、select等标签会自动维持自身的状态,但在react中,这些状态通常保存在组件的state中,并且只能用setState()来更新,如:

import react from "react";

class Hello extends react.Component {
  constructor(props) {
    super(props);
    this.state = { value: "Hello react." };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({ value: e.target.value });
  }

  render() {
    var value = this.state.value;
    return (
      <div>
        <input type="text" value={value} onChange={this.handleChange} />
        <h4>{value}</h4>
      </div>
    );
  }
}

export default Hello;

Ajax请求

在React中实现Ajax请求,通常可以使用fetch API或者第三方库如axios、jquery等库来进行网络请求,fetch API示例:

import React, { useState, useEffect } from "react";

const Hello = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(
          "http://localhost:3000/static/js/bundle.js"
        );
        const result = await response.text();
        setData(result);
        setLoading(false);
      } catch (error) {
        console.error("Error fetching data:", error);
      }
    };

    fetchData();
  }, []);

  if (loading) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>Data from API:</h1>
      <pre>{data}</pre>
    </div>
  );
};

export default Hello;

CSS样式

React应用的样式处理方式与HTML中的样式处理方式基本一致,使用CSS类名来定义样式,并通过JS代码来动态修改样式。

内联样式

import React from "react";

const Hello = ({ name }) => (
  <div className="greeting">
    <h1 style={{ color: "red" }}>Hello, {name}!</h1>
    <small>Welcome to React World</small>
  </div>
);

export default Hello;

还可以创建一个具有样式信息的对象,并在样式属性中引用它:

import React from "react";

const Hello = ({ name }) => {
  const style = {
    color: "green",
    fontSize: "24px",
  };

  return (
    <div className="greeting">
      <h1 style={style}>Hello, {name}!</h1>
      <small>Welcome to React World</small>
    </div>
  );
};

export default Hello;

样式文件

创建一个hello.css的样式文件:

body {
  background-color: #282c34;
  color: white;
  padding: 40px;
  font-family: Sans-Serif;
  text-align: center;
}

然后在应用中引入该样式文件:

import React from "react";
import "./hello.css";

const Hello = ({ name }) => {
  const style = {
    color: "green",
    fontSize: "24px",
  };

  return (
    <div className="greeting">
      <h1 style={style}>Hello, {name}!</h1>
      <small>Welcome to React World</small>
    </div>
  );
};

export default Hello;

CSS Modules

创建一个hello.module.css的样式文件:

.greeting {
  background-color: #282c34;
  color: white;
  padding: 40px;
  font-family: Sans-Serif;
  text-align: center;
}

在应用中导入该样式文件:

import React from "react";
import styles from "./hello.module.css";

const Hello = ({ name }) => {
  const style = {
    color: "green",
    fontSize: "24px",
  };

  return (
    <div className={styles.greeting}>
      <h1 style={style}>Hello, {name}!</h1>
      <small>Welcome to React World</small>
    </div>
 );
}

六、路由

React路由是单页面应用(SPA)实现页面导航的核心机制,React Router是目前最流行的React路由解决方案,与传统的路由相比:

传统服务端路由 React Router 客户端路由
每次 URL 变化都会向服务器发送请求 URL 变化不会触发页面刷新
服务器返回完整的 HTML 页面 只更新局部 DOM 内容
页面会完全刷新 保持应用状态不变

首先需要安装React Router:

npm install --save react-router-dom

主要组件:

  • BrowserRouter:用于包裹整个应用,使用BrowserRouter包裹后,React Router会自动监听浏览器的URL变化,并自动更新页面。
  • Route:用于定义路由规则,当浏览器的URL匹配到Route的path时,React Router会自动渲染Route的组件。
  • Link:用于实现页面的导航,当点击Link时,React Router会自动切换到对应的路由页面。
  • Outlet:嵌套路由占位符

自定义页面:

//home.js
const Home = () => {
  return <h2>Home</h2>;
};
export default Home;
//about.js
const About = () => {
  return <h2>About</h2>;
};
export default About;

//user.js
import { useParams } from "react-router-dom";

{
  /*动态路由,可以在路径中包含参数*/
}
const User = () => {
  const { userId } = useParams();
  return <h2>你好,{userId}</h2>;
};
export default User;

//laout.js
import { Outlet, Link } from "react-router-dom";

{
  /*嵌套路由*/
}
const Layout = () => {
  return (
    <div>
      <nav>
        <ul>
          <li>
            <Link to="profile">Profile</Link>
          </li>
          <li>
            <Link to="settings">Settings</Link>
          </li>
        </ul>
      </nav>
      {/*嵌套路由占位符*/}
      <Outlet />
    </div>
  );
};

export default Layout;
//profile.js
const Profile = () => {
  return <h2>Profile</h2>;
};
export default Profile;

//settings.js
const Settings = () => {
  return <h2>Settings</h2>;
};
export default Settings;

应用页面:

import logo from "./logo.svg";
import "./App.css";
import { BrowserRouter, Routes, Route, Link, Navigate } from "react-router-dom";
import Home from "./home";
import About from "./about";
import User from "./user";
import Layout from "./layout";
import Profile from "./profile";
import Settings from "./seetings";

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home|</Link>
        <Link to="/about">About|</Link>
        <Link to="/user/123">User|</Link>
        <Link to="/layout">Layout</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        {/*动态传参*/}
        <Route path="/user/:userId" element={<User />} />
        {/*嵌套路由*/}
        <Route path="/layout" element={<Layout />}>
          <Route path="profile" element={<Profile />} />
          <Route path="settings" element={<Settings />} />
        </Route>
        {/*404 URL重定向*/}
        <Route path="*" element={<Navigate to="/" replace />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

七、核心概念图解

graph TD A[JSX] --> B[虚拟DOM] B --> C[Diff算法] C --> D[实际DOM更新] E[Props] --> F[组件通信] G[State] --> H[UI更新]

学习资源推荐


📌 学习提示:建议配合实际项目练习,从简单组件开始逐步构建复杂应用。掌握组件通信(props/context)和状态管理后,可进一步学习React Router和状态管理库。

posted @ 2025-04-18 13:33  破落户儿  阅读(209)  评论(0)    收藏  举报