Skip to content

1.模板语法

1-1.JSX

jsx
function App() {
	return (
		<div>
			<h1>Hello, World!</h1>
			<p>This is a simple JSX example.</p>
		</div>
	);
}

1-2.模板插值

jsx
function App() {
	return (
		<div>
			<h1>Hello, {name}!</h1>
			<p>{isLoggedIn ? <p>欢迎回来</p> : <p>请登录</p>}</p>
		</div>
	);
}

1-3.属性绑定

jsx
<img src={avatarUrl} alt="头像" />

2.组件系统

2-1.函数式组件

jsx
import React, { useState, useEffect } from 'react';

function FunctionalCounter() {
  // 使用 useState Hook 管理状态
  const [count, setCount] = useState(0);
  const [message, setMessage] = useState('');

  // 使用 useEffect Hook 处理副作用
  useEffect(() => {
    document.title = `点击了 ${count} 次`;

    if (count > 5) {
      setMessage('点击次数已经超过5次了!');
    } else {
      setMessage('');
    }
  }, [count]); // 仅在 count 变化时执行

  // 事件处理函数
  const handleIncrement = () => {
    setCount(prevCount => prevCount + 1);
  };

  const handleReset = () => {
    setCount(0);
  };

  return (
    <div>
      <h2>函数式组件计数器</h2>
      <p>当前计数: {count}</p>
      <p style="color: 'red'">{message}</p>
      <button onClick={handleIncrement}>增加</button>
      <button onClick={handleReset}>重置</button>
    </div>
  );
}

export default FunctionalCounter;

2-2.类组件

jsx
import React, { Component } from 'react';

class ClassCounter extends Component {
  // 构造函数初始化状态
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      message: ''
    };

    // 绑定方法
    this.handleIncrement = this.handleIncrement.bind(this);
    this.handleReset = this.handleReset.bind(this);
  }

  // 生命周期方法
  componentDidMount() {
    document.title = `点击了 ${this.state.count} 次`;
  }

  componentDidUpdate() {
    document.title = `点击了 ${this.state.count} 次`;

    if (this.state.count > 5 && !this.state.message) {
      this.setState({ message: '点击次数已经超过5次了!' });
    } else if (this.state.count <= 5 && this.state.message) {
      this.setState({ message: '' });
    }
  }

  // 类方法
  handleIncrement() {
    this.setState(prevState => ({
      count: prevState.count + 1
    }));
  }

  handleReset() {
    this.setState({ count: 0 });
  }

  render() {
    return (
      <div>
        <h2>Class 组件计数器</h2>
        <p>当前计数: {this.state.count}</p>
        <p style="color: 'red'">{message}</p>
        <button onClick={this.handleIncrement}>增加</button>
        <button onClick={this.handleReset}>重置</button>
      </div>
    );
  }
}

export default ClassCounter;

3.生命周期

React 函数式组件 (Hooks)Vue 3 组合式 API说明
useState + useEffectsetup() + ref()组件初始化阶段
useEffect(() => {}, [])onMounted()组件挂载完成后执行(相当于 componentDidMount)
useEffect(() => { return () => {} }, [])onUnmounted()组件卸载时执行清理(相当于 componentWillUnmount)
useEffect(() => {}, [dep])onUpdated() / watch依赖项变化时执行(相当于 componentDidUpdate)
useMemo/useCallbackcomputed/watch性能优化,避免不必要的计算/渲染

4.Props

React props 是一个对象,包含了组件接收的所有属性。

  • 父组件可以传递任意类型的数据:字符串数字布尔值对象函数JSX 等。
  • 子组件通过参数或 props 对象访问这些数据。
jsx
// 父组件
function App() {
  return <Welcome name="Alice" />;
}

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

而在 react 中,父子通信的设计,相对来说比 Vue 直接利用 props 传递参数即可:

jsx
// 父组件
function App() {
  const handleClick = () => {
    console.log('React Button clicked')
  }

  return <Button onClick={handleClick} />
}
jsx
// 子组件
function Button({ onClick }) {
  return <button onClick={onClick}>Click me</button>
}

5.Events

React 事件是对浏览器原生事件的封装。

React 使用的是一个叫做**合成事件(SyntheticEvent)**的系统,它封装了原生 DOM 事件,为了实现更好的跨浏览器兼容性和性能。

譬如 React 中使用的是 on 前缀来绑定事件,而不是 Vue 中的 v-on

jsx
function MyButton() {
	return (
		<button onClick={() => alert('Button clicked!')}>
			Click me
		</button>
	)
}

6.Refs

refReact 提供的一个特殊属性,用来获取某个组件或 DOM 节点的引用。

常用于需要直接操作 DOM,或者调用子组件的实例方法(class 组件)时。

jsx
// 函数式组件
import React from 'react'

function MyComponent() {
  const inputRef = React.useRef(null) // 创建 ref

  const focusInput = () => {
    inputRef.current.focus()  // 通过 ref 访问 DOM 节点
  }

  return (
    <>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>聚焦输入框</button>
    </>
  )
}
jsx
// 类组件
class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.inputRef = React.createRef()
  }

  focusInput = () => {
    this.inputRef.current.focus()
  }

  render() {
    return (
      <>
        <input ref={this.inputRef} type="text" />
        <button onClick={this.focusInput}>聚焦输入框</button>
      </>
    )
  }
}

7.Slots

Vue 中,slots 是一种允许父组件向子组件传递内容的机制。分为默认插槽具名插槽

而在 React 中可分别用 props.children自定义props来实现这个功能:

jsx
function Layout({ header, footer, children }) {
  return (
    <div>
      <header>{header}</header>
      <main>{children}</main>
      <footer>{footer}</footer>
    </div>
  )
}

function App() {
  return (
    <Layout
      header={<h1>这是头部</h1>}
      footer={<small>这是尾部</small>}
    >
      <p>这里是主体内容</p>
    </Layout>
  )
}

8.性能优化

8-1.React.memo

React.memo 是一个高阶组件,用于优化组件的渲染性能。

它可以缓存组件的渲染结果,避免不必要的重新渲染,只有当 props 改变时才重新渲染

jsx
import React from 'react';

function MyComponent(props) {
	return <div>{props.value}</div>;
}

export default React.memo(MyComponent);

TIP

Vue 中可以看做 v-oncedefineComponent + shallowRef + watchEffect 等。

8-2.useMemo

useMemo 是一个 Hook,用于缓存计算结果,避免在每次渲染时都重新计算。

jsx
import React, { useMemo } from 'react';

function MyComponent(props) {
	const computedValue = useMemo(() => {
		return expensiveCalculation(props.value);
	}, [props.value]); // 仅在 props.value 改变时重新计算

	return <div>{computedValue}</div>;
}

function expensiveCalculation(value) {
	// 模拟一个耗时的计算
	let result = 0;
	for (let i = 0; i < 1000000; i++) {
		result += value;
	}
	return result;
}

TIP

Vue 中可以看做 computed

8-3.useCallback

useCallback 是一个 Hook,用于缓存函数实例,避免在每次渲染时都创建新的函数。

jsx
import React, { useCallback } from 'react';

function MyComponent({ onClick }) {
	const handleClick = useCallback(() => {
		onClick();
	}, [onClick]); // 仅在 onClick 改变时重新创建函数

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

TIP

Vue 通常不需要 useCallback 类似的功能,因为:

  • 方法写在 methodssetup 里本来就只创建一次。

  • Vue 子组件不会因为传入的方法地址变化就重新渲染(不是纯函数式组件)。

8-4.组件懒加载

React 支持懒加载组件,可以使用 React.lazySuspense 来实现。

jsx
import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

export default function App() {
	return (
		<Suspense fallback={<div>Loading...</div>}>
			<LazyComponent />
		</Suspense>
	);
}

TIP

Vue 中可以使用 defineAsyncComponent 来实现类似的功能。

javascript
import { defineAsyncComponent } from 'vue';

export default {
	components: {
		AsyncComponent: defineAsyncComponent(() => import('./AsyncComponent.vue'))
	}
}
html
<template>
	<Suspense>
		<template #default>
			<AsyncComponent />
		</template>
		<template #fallback>
			<div>加载中...</div>
		</template>
	</Suspense>
</template>