React学习笔记:从JSX到组件化开发

103 阅读8分钟

React学习笔记:从JSX到组件化开发

React作为现代前端开发的主流框架之一,以其独特的组件化思想和高效的渲染机制赢得了广泛的应用。React的核心亮点在于JSX语法,它将XML元素直接嵌入JavaScript中,使得开发者能够以声明式方式编写用户界面 。与Vue等其他前端框架相比,React采用更激进的开发方式,入门门槛相对较高,但其强大的生态系统和灵活的架构设计使其成为构建复杂Web应用的理想选择。

一、React概述与现代前端框架定位

React是由Facebook开发并维护的一个专注于构建用户界面的JavaScript库 。它采用组件化开发模式,将用户界面拆分为多个独立的组件,每个组件负责特定功能,通过组合这些组件来构建完整的应用 。React的核心思想是"声明式UI",开发者只需描述界面在给定状态下的样子,React会自动处理界面更新。

在现代前端框架生态中,React占据着重要地位。根据2025年的最新数据,React在企业采用率方面领先于Vue,LinkedIn上React岗位数量是Vue的2.3倍 。React的优势主要体现在以下几个方面:

首先,React拥有强大的设计团队和社区支持。Facebook(现Meta)的前端团队持续维护和更新React,确保其技术领先性和稳定性。React社区活跃度高,GitHub贡献者数量是Vue的2.1倍 ,这意味着开发者可以轻松找到解决方案和最佳实践。

其次,React的生态系统非常丰富。从状态管理(Redux)、路由(React Router)到UI组件库(Ant Design、Material UI)等,React拥有完善的工具链,开发者可以根据项目需求灵活选择和集成这些工具。

第三,React的跨平台能力出色。React Native允许开发者使用相同的React语法构建移动应用,代码复用率可达85%以上 。这种能力使React在全栈和跨平台开发中具有独特优势。

最后,React持续演进,不断引入创新特性。2025年发布的React 19引入了React Compiler、Server Components和新的Hooks(如useOptimistic) ,进一步简化了开发流程并提升了性能。

二、JSX语法详解

JSX(JavaScript XML)是React的核心语法特性,它是一种JavaScript的语法扩展,允许开发者在JavaScript中编写类似XML的元素 。JSX的本质是让开发者能够在JavaScript中直接描述UI结构,从而实现声明式编程 。最终,JSX会被编译为React.createElement()函数调用,创建React元素。

1. JSX基本语法特点

JSX语法与HTML高度相似,但有一些重要区别:

首先,JSX元素是自闭合的。例如,<img />在JSX中是有效的,而在HTML中可能需要写成<img><img />

其次,JSX中使用大括号{}来嵌入动态表达式。例如:

const name = "React";
return <h1>Hello, {name}</h1>;

第三,JSX中使用className代替HTML的class属性,使用htmlFor代替for属性。这是因为classfor是JavaScript的保留关键字。

第四,JSX中可以使用条件表达式和逻辑与操作符。例如:

{isLoggedIn ? <p>欢迎回来!</p> : <p>请登录。</p>}
{isLoggedIn && <button>退出登录</button>}

第五,JSX中可以使用数组展开运算符来渲染多个元素。例如:

const items = ["React", "JSX", "Hooks"];
return <ul>{items.map(item => <li>{item}</li>)}</ul>;

2. JSX编译原理

当编写JSX代码时,实际上是在编写一种扩展的JavaScript语法。在构建过程中,JSX会被编译为React.createElement()函数调用 ,该函数接受三个参数:标签名、属性对象和子元素。

例如,以下JSX代码:

<div id="title">
  <span className="title_span">Hello, React</span>
</div>

会被编译为:

React.createElement("div", { id: "title" },
  React.createElement("span", { className: "title_span" }, "Hello, React")
);

这种编译过程使得React能够高效地管理虚拟DOM,并通过Diff算法最小化实际DOM操作。

3. JSX与HTML的差异

JSX与HTML虽然语法相似,但在使用上有明显差异:

特性JSXHTML
类名classNameclass
样式内联样式使用对象使用CSS文件
属性值表达式用大括号包裹字符串用引号包裹
自闭合标签必须闭合或使用自闭合语法可以省略闭合标签
事件处理使用on前缀(如onClick)使用原生事件名(如click)
表达式可以使用JavaScript表达式仅限静态内容

4. TypeScript中的JSX类型支持

在TypeScript项目中使用JSX时,可以为组件和属性添加类型定义,增强代码的可维护性和安全性 。

interface GreetingProps {
  name: string;
  enthusiasmLevel?: number;
}

const Greeting: React.FC <GreetingProps> = ({ name, enthusiasmLevel = 1 }) => {
  const exclamationMarks = '!'.repeat(enjoymentLevel);
  return <h1>{`Hello${name融资exclamationMarks}!`}</h1>;
};

在TypeScript配置文件中,需要设置jsx选项:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react"
  }
}

三、React组件概念、创建方式与组合方法

1. 组件概念与基本结构

React组件是UI的基本构建单元,它接收props作为输入,并返回JSX元素描述界面。组件可以是函数组件或类组件,但自React 16.8引入Hooks以来,函数组件已成为官方推荐的主流创建方式。

一个典型的React组件结构如下:

function JuejinHeader() {
  return (
    <div>
      <header>
        <h1>JueJin首页</h1>
      </header>
    </div>
  );
}

2. 函数组件与类组件对比

特性函数组件类组件
状态管理useState等Hooksthis.state与setState
副作用处理useEffect组件生命周期方法
逻辑复用自定义Hooks高阶组件或混合模式
代码简洁性更简洁较复杂,需继承React.Component
性能更优,可记忆化可能有性能开销
开发体验更好,心智模型简单初学较难,需理解this绑定

函数组件通过Hooks提供了更直观的状态管理和副作用处理方式 。例如,使用useEffect可以替代类组件的componentDidMount、componentDidUpdate和componentWillUnmount等生命周期方法 。

// 函数组件示例
function Clock() {
  const [date, setDate] = useState(new Date());

  useEffect(() => {
    const timer = setInterval(() => {
      setDate(new Date());
    }, 1000);
    return () => clearInterval(timer);
  }, []);

  return <div>当前时间:{date.toString()}</div>;
}

3. 组件组合模式

React组件可以通过多种方式组合,形成复杂的应用界面:

基础组合:通过嵌套和props传递实现父子组件通信 。

function App() {
  return (
    <div>
      <JuejinHeader />
      <main>
        <Articles />
        <aside>
          <Checkin />
          <Top Articles />
        </aside>
      </main>
    </div>
  );
}

高阶组件(HOC):接收组件并返回增强后的新组件,适用于数据注入、权限控制等场景 。

const withAuth = (WrappedComponent) => {
  return (props) => {
    const isAuthenticated = localStorage.getItem('token');
    if (!isAuthenticated) {
      return <Redirect to="/login" />;
    }
    return <裹住的组件 {...props} />;
  };
};

const ProtectedDashboard = withAuth(Dashboard);

渲染道具:通过函数prop动态控制渲染内容,实现逻辑复用 。

const MouseTracker = ({ render }) => {
  const [pos, setPos] = useState({ x: 0, y: 0 });

  return (
    <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
      {render(pos)}
    </div>
  );
};

// 使用示例
<MouseTracker
  render={(pos) => <p>鼠标位置:{pos.x}, {pos.y}</p>}
/>

复合组件:组合多个组件形成新功能 。

const InputWithLabel = ({ label, ...props }) => {
  return (
    <div>
      <label>{label}</label>
      <input {...props} />
    </div>
  );
};

4. 组件最佳实践

组件粒度:保持组件小而专注,遵循单一职责原则。

组件命名:使用名词或名词短语,避免动词,保持一致性。

状态提升:将共享状态提升到最近的共同父组件中。

性能优化:使用React.memo避免不必要的渲染,或使用PureComponent进行浅比较。

// 使用React.memo优化性能
const MemoizedCheckin = React.memo(Checkin);

// 或使用PureComponent
class PureCheckin extends React.PureComponent {
  // ...
}

四、React状态管理机制与常用Hooks

React的状态管理机制经历了从类组件的this.state到函数组件Hooks的演变。随着React 16.8引入Hooks,函数组件现在能够轻松管理状态和副作用 ,成为构建React应用的首选方式。

1. 基础状态管理Hooks

useState:用于管理组件内部状态 。

function App() {
  const [name, setName] = useState('vue');
  const [todos, setTodos] = useState([
    {
      id: 1,
      title: '学习React',
      done: false,
    },
    // 其他待办事项...
  ]);
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  // 切换登录状态
  const toggleLoggedIn = () => {
    setIsLoggedIn(!isLoggedIn);
  };

  return (
    <div>
      <h1>Hello <span className='title}>{name}</span></h1>
      {isLoggedIn ? <div>已登录</div> : <div>未登录</div>}
      <button onClick={toggleLoggedIn}>
        {isLoggedIn ? '退出登录' : '登录'}
      </button>
    </div>
  );
}

useEffect:用于处理副作用,如数据获取、订阅等 。

useEffect(() => {
  // 组件挂载时执行
  fetchData();

  // 组件卸载时清理
  return () => {
    cleanup();
  };
}, [dependency]); // 依赖数组控制何时重新执行

2. 高级状态管理Hooks

useContext:用于在组件树中共享状态,避免props钻取 。

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

// Provider组件
function App() {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      < JuejinHeader />
      <main>
        <Articles />
      </main>
    </ThemeContext.Provider>
  );
}

// 使用Context
function ThemedButton() {
  const { theme } = React.useContext(ThemeContext);

  return <button className={`button button-${theme}`}>按钮</button>;
}

useReducer:用于管理复杂状态逻辑,通常与Context API结合使用 。

const todoReducer = (state, action) => {
  switch (action.type) {
    case 'ADDTODO':
      return [...state, { id: Date.now(), text: action.text, done: false }];
    case 'TOGGLEDONE':
      return state.map(todo =>
        todo.id === action.id ? { ...todo, done: !todo.done } : todo
      );
    default:
      return state;
  }
};

function TodoApp() {
  const [todos, dispatch] = useState(todoReducer, []);
  // ...
}

3. React 19新增状态管理Hooks

React 19引入了一系列新Hooks,进一步简化了状态管理和副作用处理

useOptimistic:用于乐观更新UI,提升用户体验 。

function TodoList({ todos }) {
  const [optimisticTodos, addOptimisticTodo] = useOptimistic(
    todos,
    (state, newTodo) => [...state, { ...newTodo, pending: true }]
  );

  const addTodo = async (text) => {
    const newTodo = { id: Date.now(), text };
    addOptimisticTodo(newTodo);

    try {
      await createTodo(text);
    } catch (err) {
      // 错误处理
    }
  };

  return (
    <ul>
      {optimisticTodos.map(todo => (
        <li
          key={todo.id}
          className={todo.pending ? 'pending' :"}
        >
          {todo.text}
        </li>
      ))}
    </ul>
  );
}

useFormStatus:与表单操作协同,感知表单状态 。

useFormState:管理表单提交状态和响应 。

这些新Hooks使得React在表单管理和状态同步方面更加简洁高效。

五、完整React应用示例与最佳实践

1. Next.js与React 19构建Todo应用

Next.js是一个基于React的全栈框架,支持服务端渲染(SSR)和静态站点生成(SSG) 。结合React 19的Server Components和新Hooks,可以构建高性能的现代Web应用。

项目结构

src/
  app/
    todo/
      page.tsx
      components/
        TodoForm.tsx
        TodoList.tsx
        TodoItem.tsx
      contexts/
        TodoContext.tsx
  lib/
    api.ts
  styles/
    global.css

服务端组件(TodoList)

// src/app/todo/page.tsx
import TodoForm from './components/TodoForm';
import TodoList from './components/TodoList';
import TodoContextProvider from './contexts/TodoContext';

export default function TodoPage() {
  return (
    <TodoContextProvider>
      <div className="min-h-screen p-8">
        <h1 className="text-3xl font-bold mb-8 text-center">Todo List</h1>
        <TodoForm />
        <TodoList />
      </div>
    </TodoContextProvider>
  );
}

客户端组件(TodoForm)

// src/appTODO/page.tsx
// "use client"; // 表示这是一个客户端组件
import { useState } from 'react';

export default function TodoForm() {
  const [inputValue, setInputValue] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (inputValue.trim() === '') return;

    // 使用useOptimistic实现乐观更新
    // ...

    // 提交到服务器
    // ...

    setInputValue('');
  };

  return (
    <form onSubmit={handleSubmit} className="mb-8">
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        placeholder="添加新的待办事项..."
        className="px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
      />
      <button
        type="submit"
        className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
      >
        添加
      </button>
    </form>
  );
}

状态管理(TodoContext)

// src/appTODO/contexts/TodoContext.tsx
import { createContext, useState, useEffect } from 'react';

export const TodoContext = createContext();

export function TodoContextProvider({ children }) {
  const [todos, setTodos] = useState([]);
  const [inputValue, setInputValue] = useState('');

  // 从服务器获取初始数据
  useEffect(() => {
    fetch('/api/todos')
      .then(res => res.json())
      .then(data => setTodos(data));
  }, []);

  // 添加Todo
  const addTodo = async (text) => {
    // 乐观更新
    // ...

    // 提交到服务器
    // ...

    // 更新状态
    // ...
  };

  // 切换Todo完成状态
  const toggleTodo = (id) => {
    setTodos(todos.map(todo =>
      todo.id === id ? { ...todo, done: !todo.done } : todo
    ));
  };

  return (
    <TodoContext.Provider value={{ todos, addTodo, toggleTodo }}>
      {children}
    </TodoContext.Provider>
  );
}

2. React最佳实践

代码组织:按功能或组件类型组织代码,避免深层嵌套。

性能优化:使用React.memo避免不必要的渲染,使用useMemo缓存计算结果 。

const MemoizedTodoItem = React.memo(TodoItem);

const TodoList = ({ todos }) => {
  const optimizedTodos = React.useMemo(() => {
    // 复杂计算
    return todos;
  }, [todos]);

  return (
    <ul>
      {optimizedTodos.map(todo => (
        <MemoizedTodoItem key={todo.id} todo={todo} />
      ))}
    </ul>
  );
};

错误处理:使用ErrorBoundary捕获组件树中的错误 。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新状态以显示错误UI
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // 显示备用UI
      return <h1>发生了错误。</h1>;
    }

    return this.props.children;
  }
}

// 使用ErrorBoundary
<ErrorBoundary>
  <TodoList />
</ErrorBoundary>

测试策略:使用Jest和React Testing Library进行单元测试和集成测试。

// TodoForm测试
import { render, screen, fireEvent } from '@testing-library/react';
import TodoForm from './TodoForm';

test('添加Todo', async () => {
  render(<TodoForm />);

  const input = screen.getByPlaceholderText('添加新的待办事项...');
  const button = screen.getByText('添加');

  fireEvent change(input, { target: { value: '学习React Hooks' } });
  await act(() =>火灾Event click(button));

  expect(screen.getByText('学习React Hooks')).toBeInTheDocument();
});

构建优化:使用SWC编译器替代Babel,提升构建性能 。

// vite.config.ts
import react from '@vitejs/plugin-react-swc';

export default defineConfig({
  plugins: [
    react({
     jsxImportSource: '@emotion/react',
      tsDecorators: true,
    }),
  ],
});

六、总结与学习路径建议

React作为现代前端开发的主流框架,其核心优势在于组件化开发和高效的渲染机制。JSX语法是React的亮点,它允许开发者在JavaScript中直接描述UI结构,实现声明式编程 。虽然React的入门门槛相对较高,但其强大的生态系统和灵活的架构设计使其成为构建复杂Web应用的理想选择。

对于React学习,建议采取以下路径:

首先,掌握React基础概念和JSX语法,理解组件化思想和虚拟DOM机制。

其次,深入学习React Hooks,特别是useState、useEffect等基础Hooks,以及useContext、useReducer等高级Hooks。

第三,了解React生态中的常用工具,如React Router、Redux、Ant Design等,掌握它们与React的集成方式。

最后,实践构建完整应用,从简单组件开始,逐步构建复杂界面,学习状态管理和性能优化技巧。

通过系统学习和实践,开发者可以充分发挥React的优势,构建高性能、可维护的现代Web应用。React的持续演进和创新特性(如React 19的Server Components和新Hooks)将继续推动前端开发的发展,为开发者提供更简洁高效的状态管理方式。