React完整学习指南:从入门到精通(从根class->本hooks)16-19完整对比

大家好,我是鱼樱!!!

关注公众号【鱼樱AI实验室】持续每天分享更多前端和AI辅助前端编码新知识~~喜欢的就一起学反正开源至上,无所谓被诋毁被喷被质疑文章没有价值~~~坚持自己观点

一个城市淘汰的自由职业-农村前端程序员(虽然不靠代码挣钱,写文章就是为爱发电),兼职远程上班目前!!!热心坚持分享~~~

今天为大家分享一份React完整学习指南仅供参考学习方向和思路~

目录

  • 第一部分:React基础知识
  • 第二部分:React版本演进(16-19)
  • 第三部分:组件与Props
  • 第四部分:状态管理
  • 第五部分:生命周期方法
  • 第六部分:React Hooks基础
  • 第七部分:常用Hooks详解
  • 第八部分:自定义Hooks开发
  • 第九部分:第三方Hooks库
  • 第十部分:性能优化策略
  • 第十一部分:TypeScript最佳实践
  • React性能优化深度指南
  • 状态管理全面指南:Redux/MobX/Zustand最佳实践
  • 结语:React学习路径推荐

第一部分:React基础知识

1.1 React简介

React是由Facebook开发的声明式UI库,主要用于构建用户界面。它的核心思想是:

  • 组件化开发:将UI拆分为独立、可复用的小组件
  • 单向数据流:数据从父组件流向子组件
  • 虚拟DOM:提高渲染性能

1.2 搭建React开发环境

使用Create React App

sh 复制代码
 
npx create-react-app my-app
cd my-app
npm start

使用Vite(更现代的构建工具)

sh 复制代码
 
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run dev

1.3 JSX基础

JSX是JavaScript的语法扩展,让你在JavaScript中编写类似HTML的代码。

tsx 复制代码
 
// JSX语法示例
const element = <h1>Hello, world!</h1>;

// 使用表达式
const name = "React";
const element = <h1>Hello, {name}!</h1>;

// 多行JSX需要用括号包裹
const element = (
  <div>
    <h1>Hello!</h1>
    <p>Welcome to React</p>
  </div>
);

JSX的关键特性

  • JSX会被Babel编译为React.createElement()调用
  • JSX中使用camelCase命名属性 ,如className而不是class
  • JSX中可以嵌入JavaScript表达式,使用{}包裹
  • JSX本身也是表达式,可以在JS逻辑中使用

第二部分:React版本演进(16-19)

2.1 React 16的主要特性

  • Fiber架构 :完全重写的核心算法,支持增量渲染
  • Error Boundaries:更好的错误处理
  • Portals:将子节点渲染到DOM树的不同位置
  • 服务端渲染改进
  • 支持自定义DOM属性

2.2 React 17的主要特性

  • 无新特性:这是一个过渡版本
  • 事件委托系统改变:从document变为React树的根DOM容器
  • 更好的JSX转换:不再需要导入React
  • 渐进式升级支持:可以在同一页面运行多个React版本

2.3 React 18的主要特性

  • 并发渲染:React可以准备多个UI版本同时存在
  • 自动批处理:多个状态更新会被批处理
  • Suspense SSR:流式服务端渲染
  • 新的Root APIReactDOM.createRoot()
  • 新的HooksuseId, useTransition, useDeferredValue

2.4 React 19的主要特性

  • Actions:组件级别的数据获取和修改
  • Compiler优化:专门针对React的编译优化
  • React Forget:自动记忆化
  • 文档组件支持:更好的服务器组件支持
  • React Hooks改进:更好的调试体验

第三部分:组件与Props

3.1 函数组件

tsx 复制代码
 
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

3.2 类组件

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

3.3 组件组合

组合组件是React的强大特性,可以构建复杂UI:

tsx 复制代码
 
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

3.4 Props的特性

  • Props是只读的,不应该修改它们
  • Props可以传递任何JavaScript值,包括函数和JSX
  • 可以使用解构来简化代码
tsx 复制代码
 
function Welcome({ name, age }) {
  return <h1>Hello, {name}, you are {age} years old</h1>;
}

第四部分:状态管理

4.1 类组件中的状态

tsx 复制代码
 
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>
    );
  }
}

4.2 使用useState Hook

tsx 复制代码
 
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

4.3 状态更新注意事项

  • 状态更新可能是异步的
  • 状态更新会合并 (类组件)或替换(函数组件)之前的状态
  • 依赖之前的状态时,应该使用函数形式
tsx 复制代码
 
// 类组件
this.setState(prevState => ({ count: prevState.count + 1 }));

// 函数组件
setCount(prevCount => prevCount + 1);

第五部分:生命周期方法

5.1 React 16.3之前的生命周期

类组件的生命周期可分为三个阶段:

挂载阶段

  • constructor() - 初始化state和绑定方法
  • componentWillMount() (已废弃)
  • render() - 返回需要渲染的元素
  • componentDidMount() - 组件挂载后执行,适合网络请求

更新阶段

  • componentWillReceiveProps(nextProps) (已废弃)
  • shouldComponentUpdate(nextProps, nextState) - 决定是否重新渲染
  • componentWillUpdate(nextProps, nextState) (已废弃)
  • render()
  • componentDidUpdate(prevProps, prevState) - 更新后执行

卸载阶段

  • componentWillUnmount() - 组件卸载前执行清理工作

5.2 React 16.3及之后的生命周期

React 16.3引入了新的生命周期方法,废弃一些旧方法:

新增的生命周期方法

  • getDerivedStateFromProps(props, state) - 替代componentWillReceiveProps
  • getSnapshotBeforeUpdate(prevProps, prevState) - 在DOM更新前捕获信息

废弃的生命周期方法(带UNSAFE_前缀):

  • UNSAFE_componentWillMount()
  • UNSAFE_componentWillReceiveProps()
  • UNSAFE_componentWillUpdate()
tsx 复制代码
 
class ExampleComponent extends React.Component {
  // 挂载阶段
  constructor(props) {
    super(props);
    this.state = { data: [] };
  }
  
  static getDerivedStateFromProps(props, state) {
    // 返回新状态或null
    return null;
  }
  
  componentDidMount() {
    // API调用等初始化操作
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => this.setState({ data }));
  }
  
  // 更新阶段
  shouldComponentUpdate(nextProps, nextState) {
    // 性能优化:控制组件是否需要重新渲染
    return true;
  }
  
  getSnapshotBeforeUpdate(prevProps, prevState) {
    // 在DOM更新前捕获信息(如滚动位置)
    return null;
  }
  
  componentDidUpdate(prevProps, prevState, snapshot) {
    // 使用snapshot更新DOM
    if (this.props.id !== prevProps.id) {
      // props变化后的操作
    }
  }
  
  // 卸载阶段
  componentWillUnmount() {
    // 清理操作:取消订阅、定时器等
  }
  
  render() {
    return <div>{this.state.data.map(item => <div key={item.id}>{item.name}</div>)}</div>;
  }
}

5.3 类组件生命周期与Hooks对应关系

类组件生命周期 Hooks对应方案
constructor useState初始化
componentDidMount useEffect(() => {}, [])
componentDidUpdate useEffect(() => {}, [dependencies])
componentWillUnmount useEffect(() => { return () => {} }, [])
shouldComponentUpdate React.memo + useMemo/useCallback
getDerivedStateFromProps useState + useEffect

第六部分:React Hooks基础

6.1 Hooks简介

Hooks 是React 16.8引入的特性,让你在不编写类组件的情况下使用状态和其他React特性。

Hooks的优势

  • 更好的逻辑复用
  • 减少复杂组件的嵌套(告别HOC和render props)
  • 更简洁的代码
  • 更容易理解的组件行为

Hooks使用规则

  • 只能在函数组件自定义Hook中调用
  • 只能在顶层调用,不能在条件语句、循环或嵌套函数中调用
  • 函数名必须以use开头

6.2 useState - 状态管理

tsx 复制代码
 
import { useState } from 'react';

function Counter() {
  // 声明一个状态变量和更新函数
  const [count, setCount] = useState(0);
  
  // 使用对象状态
  const [user, setUser] = useState({ name: '', age: 0 });
  
  // 更新对象状态(需要合并之前的状态)
  const updateName = (name) => {
    setUser(prevUser => ({ ...prevUser, name }));
  };
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>Safe Increment</button>
      
      <input 
        value={user.name} 
        onChange={e => updateName(e.target.value)} 
      />
    </div>
  );
}

6.3 useEffect - 副作用处理

tsx 复制代码
 
import { useState, useEffect } from 'react';

function DataFetcher() {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  
  // 组件挂载后获取数据
  useEffect(() => {
    const fetchData = async () => {
      try {
        setIsLoading(true);
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err);
      } finally {
        setIsLoading(false);
      }
    };
    
    fetchData();
    
    // 清理函数(相当于componentWillUnmount)
    return () => {
      // 取消请求、清除定时器等
    };
  }, []); // 空依赖数组表示只在挂载和卸载时执行
  
  // 依赖特定值变化的effect
  useEffect(() => {
    document.title = `You have ${data.length} items`;
  }, [data]); // 当data变化时执行
  
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  
  return (
    <ul>
      {data.map(item => <li key={item.id}>{item.name}</li>)}
    </ul>
  );
}

6.4 useContext - 上下文管理

tsx 复制代码
 
import { createContext, useContext, useState } from 'react';

// 创建上下文
const ThemeContext = createContext('light');

function App() {
  const [theme, setTheme] = useState('light');
  
  return (
    <ThemeContext.Provider value={theme}>
      <div>
        <ThemedButton />
        <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
          Toggle Theme
        </button>
      </div>
    </ThemeContext.Provider>
  );
}

function ThemedButton() {
  // 使用上下文
  const theme = useContext(ThemeContext);
  
  return (
    <button style={{ 
      background: theme = 'light' ? '#fff' : '#333',
      color: theme = 'light' ? '#333' : '#fff'
    }}>
      I am styled by theme context!
    </button>
  );
}

第七部分:常用Hooks详解

7.1 useReducer - 复杂状态管理

适用场景:当状态逻辑复杂、涉及多个子值或下一个状态依赖前一个状态时。

tsx 复制代码
 
import { useReducer } from 'react';

// 定义reducer函数
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return { count: 0 };
    default:
      throw new Error('Unknown action');
  }
}

function Counter() {
  // 使用reducer
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

7.2 useRef - 引用DOM和保存变量

useRef有两个主要用途:

  1. 访问DOM元素
  2. 在渲染间保持值(不触发重新渲染)
tsx 复制代码
 
import { useRef, useEffect, useState } from 'react';

function TextInputWithFocus() {
  // 创建ref
  const inputRef = useRef(null);
  const renderCountRef = useRef(0);
  const [text, setText] = useState('');
  
  // 焦点到input元素
  const focusInput = () => {
    inputRef.current.focus();
  };
  
  // 追踪组件渲染次数
  useEffect(() => {
    renderCountRef.current += 1;
    console.log(`Rendered ${renderCountRef.current} times`);
  });
  
  return (
    <div>
      <input 
        ref={inputRef} 
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={focusInput}>Focus Input</button>
      <p>Component rendered {renderCountRef.current} times</p>
    </div>
  );
}

7.3 useMemo - 记忆计算结果

用途:缓存计算结果,避免在每次渲染时重复进行昂贵的计算。

tsx 复制代码
 
import { useState, useMemo } from 'react';

function ExpensiveCalculation({ list, filter }) {
  // 使用useMemo缓存计算结果
  const filteredList = useMemo(() => {
    console.log("Computing filtered list...");
    return list.filter(item => item.includes(filter));
  }, [list, filter]); // 只有当list或filter变化时才重新计算
  
  return (
    <div>
      <p>Filtered list length: {filteredList.length}</p>
      <ul>
        {filteredList.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

function App() {
  const [filter, setFilter] = useState('');
  const [list] = useState(['apple', 'banana', 'cherry', 'date', 'elderberry']);
  
  return (
    <div>
      <input 
        value={filter}
        onChange={e => setFilter(e.target.value)}
        placeholder="Filter fruits..."
      />
      <ExpensiveCalculation list={list} filter={filter} />
    </div>
  );
}

7.4 useCallback - 记忆函数

用途:缓存函数引用,避免子组件不必要的重新渲染。

tsx 复制代码
 
import { useState, useCallback } from 'react';

// 子组件使用React.memo优化
const Button = React.memo(({ onClick, children }) => {
  console.log(`Rendering button: ${children}`);
  return <button onClick={onClick}>{children}</button>;
});

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  
  // 不使用useCallback的函数,每次渲染都会创建新的函数引用
  const incrementWithoutCallback = () => {
    setCount(c => c + 1);
  };
  
  // 使用useCallback缓存函数引用
  const incrementWithCallback = useCallback(() => {
    setCount(c => c + 1);
  }, []); // 空依赖数组表示函数引用永不变化
  
  return (
    <div>
      <p>Count: {count}</p>
      <input 
        value={text} 
        onChange={e => setText(e.target.value)}
        placeholder="Type to trigger re-render"
      />
      
      {/* 每次父组件重新渲染,这个按钮也会重新渲染 */}
      <Button onClick={incrementWithoutCallback}>
        Increment (without useCallback)
      </Button>
      
      {/* 这个按钮不会在父组件重新渲染时重新渲染 */}
      <Button onClick={incrementWithCallback}>
        Increment (with useCallback)
      </Button>
    </div>
  );
}

7.5 React 18新增的Hooks

useId - 生成唯一ID

tsx 复制代码
 
import { useId } from 'react';

function LabeledInput() {
  const id = useId();
  return (
    <div>
      <label htmlFor={id}>Email</label>
      <input id={id} type="email" />
    </div>
  );
}

useTransition - 非阻塞更新

tsx 复制代码
 
import { useState, useTransition } from 'react';

function SearchResults() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [isPending, startTransition] = useTransition();
  
  const handleChange = (e) => {
    // 立即更新输入框(高优先级)
    setQuery(e.target.value);
    
    // 在transition中更新搜索结果(低优先级)
    startTransition(() => {
      // 假设这是一个昂贵的操作
      const searchResults = performExpensiveSearch(e.target.value);
      setResults(searchResults);
    });
  };
  
  return (
    <div>
      <input value={query} onChange={handleChange} />
      {isPending ? (
        <p>Loading results...</p>
      ) : (
        <ul>
          {results.map(result => <li key={result.id}>{result.name}</li>)}
        </ul>
      )}
    </div>
  );
}

useDeferredValue - 延迟值更新

tsx 复制代码
 
import { useState, useDeferredValue } from 'react';

function SearchResults() {
  const [query, setQuery] = useState('');
  // 创建一个延迟值
  const deferredQuery = useDeferredValue(query);
  
  // 使用延迟值进行昂贵的计算
  const results = performExpensiveSearch(deferredQuery);
  
  // UI会立即响应输入,但搜索结果会使用延迟值
  return (
    <div>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      {deferredQuery !== query && <p>Loading...</p>}
      <ul>
        {results.map(result => <li key={result.id}>{result.name}</li>)}
      </ul>
    </div>
  );
}

第八部分:自定义Hooks开发

8.1 自定义Hooks基础

自定义Hooks是一种复用有状态逻辑的方式,本质上是抽取组件逻辑到可重用的函数中。

自定义Hook特点

  • 函数名必须以use开头
  • 可以调用其他Hooks
  • 返回任何需要的值
tsx 复制代码
 
// 自定义Hook:管理表单字段
function useFormField(initialValue = '') {
  const [value, setValue] = useState(initialValue);
  const [error, setError] = useState('');
  
  const handleChange = (e) => {
    setValue(e.target.value);
    if (e.target.value.trim() === '') {
      setError('This field is required');
    } else {
      setError('');
    }
  };
  
  return {
    value,
    error,
    onChange: handleChange,
    reset: () => setValue(initialValue),
  };
}

// 使用自定义Hook
function SignupForm() {
  const username = useFormField('');
  const email = useFormField('');
  const password = useFormField('');
  
  const handleSubmit = (e) => {
    e.preventDefault();
    // 表单提交逻辑
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Username</label>
        <input type="text" {...username} />
        {username.error && <p>{username.error}</p>}
      </div>
      
      <div>
        <label>Email</label>
        <input type="email" {...email} />
        {email.error && <p>{email.error}</p>}
      </div>
      
      <div>
        <label>Password</label>
        <input type="password" {...password} />
        {password.error && <p>{password.error}</p>}
      </div>
      
      <button type="submit">Sign Up</button>
    </form>
  );
}

8.2 常用自定义Hooks示例

useLocalStorage - 本地存储状态

tsx 复制代码
 
function useLocalStorage(key, initialValue) {
  // 读取初始值
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });
  
  // 更新值并存储到localStorage
  const setValue = (value) => {
    try {
      // 处理函数形式的value
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.error(error);
    }
  };
  
  return [storedValue, setValue];
}

// 使用示例
function App() {
  const [name, setName] = useLocalStorage('name', '');
  
  return (
    <div>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
        placeholder="Enter your name"
      />
      <p>Hello, {name || 'Guest'}!</p>
    </div>
  );
}

useFetch - 数据获取

tsx 复制代码
 
function useFetch(url) {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    let isMounted = true;
    const controller = new AbortController();
    
    async function fetchData() {
      setIsLoading(true);
      try {
        const response = await fetch(url, { signal: controller.signal });
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const json = await response.json();
        
        if (isMounted) {
          setData(json);
          setError(null);
        }
      } catch (err) {
        if (err.name !== 'AbortError' && isMounted) {
          setError(err.message);
          setData(null);
        }
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    }
    
    fetchData();
    
    return () => {
      isMounted = false;
      controller.abort();
    };
  }, [url]);
  
  return { data, isLoading, error };
}

// 使用示例
function UserProfile({ userId }) {
  const { data, isLoading, error } = useFetch(`https://api.example.com/users/${userId}`);
  
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;
  if (!data) return null;
  
  return (
    <div>
      <h1>{data.name}</h1>
      <p>Email: {data.email}</p>
    </div>
  );
}

第九部分:第三方Hooks库

9.1 ahooks - 阿里巴巴开源Hooks库

特点

  • 全面的Hooks集合
  • 高质量、高性能
  • 覆盖常见业务场景

常用Hooks示例

tsx 复制代码
 
// useRequest - 强大的数据请求管理Hook
import { useRequest } from 'ahooks';

function UserList() {
  const { data, loading, error, run } = useRequest(fetchUserList, {
    manual: true,
    // 请求防抖
    debounceInterval: 500,
    // 错误重试
    retryCount: 3,
    // 轮询配置
    pollingInterval: 5000
  });

  return (
    <div>
      <button onClick={run}>获取用户列表</button>
      {loading && <p>加载中...</p>}
      {error && <p>请求错误</p>}
      {data && (
        <ul>
          {data.map(user => (
            <li key={user.id}>{user.name}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

// useEventListener - 事件监听
import { useEventListener } from 'ahooks';

function KeyboardTracker() {
  const [key, setKey] = useState('');

  useEventListener('keydown', (event: KeyboardEvent) => {
    setKey(event.key);
  });

  return <div>Last pressed key: {key}</div>;
}

// useLocalStorageState - 带持久化的状态管理
import { useLocalStorageState } from 'ahooks';

function PersistentCounter() {
  const [count, setCount] = useLocalStorageState('count', {
    defaultValue: 0
  });

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(c => c + 1)}>Increment</button>
    </div>
  );
}

9.2 react-use - 全面的Hooks工具库

特点

  • 100+个实用Hooks
  • 覆盖DOM、浏览器、传感器等场景
tsx 复制代码
 
import { 
  useMedia, 
  useNetworkState, 
  useFullscreen,
  useCopyToClipboard 
} from 'react-use';

function ResponsiveComponent() {
  // 响应式媒体查询
  const isWide = useMedia('(min-width: 1200px)');
  
  // 网络状态监听
  const state = useNetworkState();
  
  // 全屏控制
  const [show, setShow] = useState(false);
  const ref = useRef(null);
  const isFullscreen = useFullscreen(ref, show, {
    onEnter: () => console.log('进入全屏'),
    onExit: () => console.log('退出全屏')
  });

  // 剪贴板操作
  const [copied, copyToClipboard] = useCopyToClipboard();

  return (
    <div ref={ref}>
      <p>屏幕宽度: {isWide ? '宽屏' : '窄屏'}</p>
      <p>网络状态: {state.online ? '在线' : '离线'}</p>
      <button onClick={() => setShow(!show)}>
        {isFullscreen ? '退出全屏' : '进入全屏'}
      </button>
      <button onClick={() => copyToClipboard('复制的文本')}>
        复制文本
      </button>
      {copied.value && <p>已复制!</p>}
    </div>
  );
}

9.3 自定义高级Hooks

useAsync - 通用异步处理

tsx 复制代码
 
function useAsync<T>(
  asyncFunction: () => Promise<T>, 
  immediate = true
) {
  const [status, setStatus] = useState<'idle' | 'pending' | 'success' | 'error'>('idle');
  const [value, setValue] = useState<T | null>(null);
  const [error, setError] = useState<Error | null>(null);

  const execute = useCallback(() => {
    setStatus('pending');
    setValue(null);
    setError(null);

    return asyncFunction()
      .then(response => {
        setValue(response);
        setStatus('success');
      })
      .catch(error => {
        setError(error);
        setStatus('error');
      });
  }, [asyncFunction]);

  useEffect(() => {
    if (immediate) {
      execute();
    }
  }, [execute, immediate]);

  return { execute, status, value, error };
}

// 使用示例
function UserProfile() {
  const fetchUser = async () => {
    const response = await fetch('/api/user');
    return response.json();
  };

  const { status, value, error, execute } = useAsync(fetchUser);

  if (status = 'pending') return <div>Loading...</div>;
  if (status = 'error') return <div>Error: {error?.message}</div>;

  return (
    <div>
      <h1>{value?.name}</h1>
      <button onClick={execute}>Refresh</button>
    </div>
  );
}

9.4 响应式状态管理Hooks

useImmer - 不可变状态更新

tsx 复制代码
 
import produce from 'immer';
import { useImmer } from 'use-immer';

interface User {
  name: string;
  age: number;
  tags: string[];
}

function UserManager() {
  const [user, updateUser] = useImmer<User>({
    name: 'John',
    age: 30,
    tags: ['developer']
  });

  const addTag = (tag: string) => {
    updateUser(draft => {
      draft.tags.push(tag);
    });
  };

  const incrementAge = () => {
    updateUser(draft => {
      draft.age += 1;
    });
  };

  return (
    <div>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
      <p>Tags: {user.tags.join(', ')}</p>
      <button onClick={() => addTag('programmer')}>
        Add Tag
      </button>
      <button onClick={incrementAge}>
        Increment Age
      </button>
    </div>
  );
}

第十部分:性能优化策略

10.1 渲染性能优化

1. React.memo - 组件记忆

tsx 复制代码
 
const ExpensiveComponent = React.memo(({ id, name }) => {
  console.log('Rendering expensive component');
  return <div>{name}</div>;
}, (prevProps, nextProps) => {
  // 自定义比较逻辑
  return prevProps.id === nextProps.id;
});

2. useMemo - 计算缓存

tsx 复制代码
 
function DataProcessor({ data }) {
  const processedData = useMemo(() => {
    return data.map(item => expensiveComputation(item));
  }, [data]);

  return <div>{processedData.length}</div>;
}

3. useCallback - 函数缓存

tsx 复制代码
 
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

10.2 代码分割

tsx 复制代码
 
// 动态导入
const LazyComponent = React.lazy(() => import('./HeavyComponent'));

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

10.3 虚拟列表优化

tsx 复制代码
 
import { FixedSizeList } from 'react-window';

function LargeList({ items }) {
  const Row = ({ index, style }) => (
    <div style={style}>
      {items[index]}
    </div>
  );

  return (
    <FixedSizeList
      height={400}
      itemCount={items.length}
      itemSize={35}
      width={300}
    >
      {Row}
    </FixedSizeList>
  );
}

第十一部分:TypeScript最佳实践

11.1 函数组件类型

tsx 复制代码
 
interface Props {
  name: string;
  age?: number;
  children?: React.ReactNode;
}

// 函数组件类型
const Greeter: React.FC<Props> = ({ name, age = 0 }) => {
  return <div>Hello {name}, {age} years old</div>;
};

// 现代推荐写法
function Greeter({ name, age = 0 }: Props) {
  return <div>Hello {name}, {age} years old</div>;
}

11.2 Hooks类型

tsx 复制代码
 
function useCustomHook<T>(initialValue: T): [T, (value: T) => void] {
  const [state, setState] = useState<T>(initialValue);
  return [state, setState];
}

React性能优化深度指南

1. 渲染性能优化策略

1.1 组件渲染优化

tsx 复制代码
 
// 使用React.memo进行浅比较
interface UserProps {
  name: string;
  age: number;
}

const UserCard = React.memo<UserProps>((props) => {
  console.log('渲染UserCard');
  return (
    <div>
      <h2>{props.name}</h2>
      <p>Age: {props.age}</p>
    </div>
  );
}, (prevProps, nextProps) => {
  // 自定义比较逻辑
  return (
    prevProps.name = nextProps.name && 
    prevProps.age = nextProps.age
  );
});

// 复杂对象的性能比较
const areEqual = (prevProps: UserProps, nextProps: UserProps) => {
  return (
    prevProps.name = nextProps.name && 
    prevProps.age = nextProps.age
  );
};

const MemoizedUserCard = React.memo(UserCard, areEqual);

1.2 useMemo性能优化

tsx 复制代码
 
function ExpensiveComponent({ data }: { data: number[] }) {
  // 仅在data变化时重新计算
  const processedData = useMemo(() => {
    console.log('计算处理数据');
    return data.map(item => {
      // 复杂计算逻辑
      return item * 2;
    });
  }, [data]);

  return (
    <div>
      {processedData.map(item => (
        <div key={item}>{item}</div>
      ))}
    </div>
  );
}

// 多依赖项的useMemo
function ComplexCalculation({ a, b, c }) {
  const result = useMemo(() => {
    return heavyCalculation(a, b, c);
  }, [a, b, c]);

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

1.3 useCallback函数记忆

tsx 复制代码
 
interface SearchProps {
  onSearch: (query: string) => void;
}

const SearchComponent = React.memo(({ onSearch }: SearchProps) => {
  const [query, setQuery] = useState('');

  // 使用useCallback缓存函数
  const handleSearch = useCallback(() => {
    onSearch(query);
  }, [query, onSearch]);

  return (
    <div>
      <input 
        value={query}
        onChange={(e) => setQuery(e.target.value)}
      />
      <button onClick={handleSearch}>搜索</button>
    </div>
  );
});

function ParentComponent() {
  // 使用useCallback避免不必要的重渲染
  const searchHandler = useCallback((query: string) => {
    console.log('搜索:', query);
  }, []);

  return <SearchComponent onSearch={searchHandler} />;
}

2. 代码分割与懒加载

tsx 复制代码
 
// 动态导入组件
const LazyComponent = React.lazy(() => import('./HeavyComponent'));

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

// 路由级懒加载
function Router() {
  return (
    <Suspense fallback={<Loader />}>
      <Routes>
        <Route 
          path="/dashboard" 
          element={
            <React.Suspense fallback={<Loader />}>
              <Dashboard />
            </React.Suspense>
          } 
        />
      </Routes>
    </Suspense>
  );
}

3. 虚拟列表优化

tsx 复制代码
 
import { FixedSizeList as List } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';

interface ItemData {
  id: number;
  name: string;
}

function VirtualizedList({ items }: { items: ItemData[] }) {
  const Row = React.memo(({ index, style }: { index: number, style: React.CSSProperties }) => {
    const item = items[index];
    return (
      <div style={style}>
        {item.name}
      </div>
    );
  });

  return (
    <AutoSizer>
      {({ height, width }) => (
        <List
          height={height}
          itemCount={items.length}
          itemSize={50}
          width={width}
        >
          {Row}
        </List>
      )}
    </AutoSizer>
  );
}

4. 性能监控与分析

tsx 复制代码
 
// 性能追踪高阶组件
function withPerformanceTracker<P>(
  WrappedComponent: React.ComponentType<P>
) {
  return class extends React.Component<P> {
    private startTime: number;

    constructor(props: P) {
      super(props);
      this.startTime = performance.now();
    }

    componentDidMount() {
      const renderTime = performance.now() - this.startTime;
      console.log(
        `Component ${WrappedComponent.name} 渲染耗时: ${renderTime}ms`
      );
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
}

// 使用性能追踪
const TrackedComponent = withPerformanceTracker(MyComponent);

5. TypeScript集成最佳实践

5.1 接口与类型定义

tsx 复制代码
 
// 组件Props类型
interface UserProfileProps {
  id: number;
  name: string;
  age?: number;
  onUpdate?: (user: UserProfileProps) => void;
}

// 复杂泛型组件
function DataFetcher<T>({
  fetchFn,
  render
}: {
  fetchFn: () => Promise<T>;
  render: (data: T) => React.ReactNode;
}) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchFn().then(result => {
      setData(result);
      setLoading(false);
    });
  }, [fetchFn]);

  return (
    <>
      {loading ? <Spinner /> : data && render(data)}
    </>
  );
}

5.2 Hooks类型定义

tsx 复制代码
 
// 泛型自定义Hooks
function useLocalStorage<T>(
  key: string, 
  initialValue: T
): [T, (value: T) => void] {
  const [storedValue, setStoredValue] = useState<T>(() => {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.log(error);
      return initialValue;
    }
  });

  const setValue = (value: T) => {
    try {
      const valueToStore = 
        value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.log(error);
    }
  };

  return [storedValue, setValue];
}

// 使用示例
function App() {
  const [name, setName] = useLocalStorage<string>('name', '');
  const [user, setUser] = useLocalStorage<UserProfileProps>('user', {
    id: 1,
    name: '',
    age: undefined
  });
}

5.3 高级类型技巧

tsx 复制代码
 
// 条件渲染类型
type RenderProps<T> = {
  data: T;
  loading?: boolean;
} & (
  | { loading: true; data?: never }
  | { loading: false; data: T }
);

function ConditionalRenderer<T>({ 
  data, 
  loading, 
  children 
}: RenderProps<T> & { 
  children: (data: T) => React.ReactNode 
}) {
  if (loading) return <Spinner />;
  return children(data);
}

// 使用示例
function App() {
  const { data, loading } = useFetch<UserProfileProps>();
  
  return (
    <ConditionalRenderer 
      data={data} 
      loading={loading}
    >
      {(userData) => (
        <UserProfile {...userData} />
      )}
    </ConditionalRenderer>
  );
}

6. 性能优化最佳实践清单

  1. 使用React.memo减少不必要渲染
  2. 正确使用useMemouseCallback
  3. 代码分割与懒加载
  4. 虚拟列表处理大数据
  5. 避免过深的组件树
  6. 减少不必要的props传递
  7. 使用useReducer管理复杂状态
  8. 合理设计状态提升策略
  9. 使用性能分析工具

性能分析工具

  • React DevTools
  • Chrome Performance
  • Lighthouse
  • WebPageTest

持续优化的原则

  • 测量
  • 优化
  • 重复

加油,成为React性能大师! 🚀🔥

状态管理全面指南:Redux/MobX/Zustand最佳实践

1. Redux深度实践

1.1 现代Redux Toolkit实践

tsx 复制代码
 
import { createSlice, configureStore, PayloadAction } from '@reduxjs/toolkit';

// 定义状态类型
interface UserState {
  id: number | null;
  name: string;
  email: string;
  isAuthenticated: boolean;
}

// 创建用户Slice
const userSlice = createSlice({
  name: 'user',
  initialState: {
    id: null,
    name: '',
    email: '',
    isAuthenticated: false
  } as UserState,
  reducers: {
    login: (state, action: PayloadAction<UserState>) => {
      state.id = action.payload.id;
      state.name = action.payload.name;
      state.email = action.payload.email;
      state.isAuthenticated = true;
    },
    logout: (state) => {
      state.id = null;
      state.name = '';
      state.email = '';
      state.isAuthenticated = false;
    }
  }
});

// 创建store
const store = configureStore({
  reducer: {
    user: userSlice.reducer
  },
  // 添加中间件
  middleware: (getDefaultMiddleware) => 
    getDefaultMiddleware({
      serializableCheck: false
    })
});

// 导出Actions和类型
export const { login, logout } = userSlice.actions;
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

// 自定义Hooks
export const useUser = () => {
  const user = useSelector((state: RootState) => state.user);
  const dispatch = useDispatch<AppDispatch>();

  const userLogin = useCallback((userData: UserState) => {
    dispatch(login(userData));
  }, [dispatch]);

  const userLogout = useCallback(() => {
    dispatch(logout());
  }, [dispatch]);

  return { user, userLogin, userLogout };
};

1.2 Redux异步Action

tsx 复制代码
 
// 创建异步Thunk
const fetchUserProfile = createAsyncThunk(
  'user/fetchProfile',
  async (userId: number, thunkAPI) => {
    try {
      const response = await axios.get(`/api/users/${userId}`);
      return response.data;
    } catch (error) {
      return thunkAPI.rejectWithValue(error.response.data);
    }
  }
);

// 处理异步Action
const userSlice = createSlice({
  name: 'user',
  initialState: {
    profile: null,
    loading: false,
    error: null
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUserProfile.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchUserProfile.fulfilled, (state, action) => {
        state.loading = false;
        state.profile = action.payload;
      })
      .addCase(fetchUserProfile.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  }
});

2. MobX响应式状态管理

tsx 复制代码
 
import { makeAutoObservable, runInAction } from 'mobx';
import { observer } from 'mobx-react-lite';

// MobX Store
class UserStore {
  // 响应式状态
  user = {
    id: null,
    name: '',
    email: ''
  };

  loading = false;
  error = null;

  constructor() {
    // 自动将所有属性转为可观察
    makeAutoObservable(this);
  }

  // 同步Action
  setUser(userData) {
    this.user = userData;
  }

  // 异步Action
  async fetchUserProfile(userId) {
    this.loading = true;
    this.error = null;

    try {
      const response = await axios.get(`/api/users/${userId}`);
      
      runInAction(() => {
        this.user = response.data;
        this.loading = false;
      });
    } catch (error) {
      runInAction(() => {
        this.error = error;
        this.loading = false;
      });
    }
  }

  // 计算属性
  get isAuthenticated() {
    return !!this.user.id;
  }
}

// 创建实例
const userStore = new UserStore();

// 响应式组件
const UserProfile = observer(() => {
  const { user, loading, error, isAuthenticated } = userStore;

  if (loading) return <Spinner />;
  if (error) return <ErrorMessage error={error} />;

  return (
    <div>
      {isAuthenticated ? (
        <div>
          <h2>{user.name}</h2>
          <p>{user.email}</p>
        </div>
      ) : (
        <LoginPrompt />
      )}
    </div>
  );
});

3. Zustand轻量级状态管理

tsx 复制代码
 
import create from 'zustand';
import { persist } from 'zustand/middleware';

// 定义状态类型
interface UserState {
  user: {
    id: number | null;
    name: string;
    email: string;
  };
  token: string | null;
  login: (userData: { id: number; name: string; email: string }) => void;
  logout: () => void;
  fetchProfile: () => Promise<void>;
}

// 创建Store
const useUserStore = create<UserState>(
  persist(
    (set, get) => ({
      user: {
        id: null,
        name: '',
        email: ''
      },
      token: null,

      // 同步登录
      login: (userData) => {
        set({ 
          user: userData,
          token: generateToken(userData)
        });
      },

      // 同步登出
      logout: () => {
        set({ 
          user: { id: null, name: '', email: '' },
          token: null 
        });
      },

      // 异步获取用户信息
      fetchProfile: async () => {
        try {
          const response = await axios.get('/api/profile', {
            headers: { 
              Authorization: `Bearer ${get().token}` 
            }
          });

          set({ user: response.data });
        } catch (error) {
          get().logout();
        }
      }
    }),
    {
      name: 'user-storage', // 本地存储key
      getStorage: () => localStorage // 存储引擎
    }
  )
);

// 组件使用
function UserProfile() {
  const { user, login, logout, fetchProfile } = useUserStore();

  useEffect(() => {
    fetchProfile();
  }, []);

  return (
    <div>
      {user.id ? (
        <>
          <h2>{user.name}</h2>
          <button onClick={logout}>退出</button>
        </>
      ) : (
        <LoginForm onLogin={login} />
      )}
    </div>
  );
}

4. 状态管理选型建议

Redux适合

  • 大型复杂应用
  • 需要详细日志和时间旅行调试
  • 多人协作大型项目

MobX适合

  • 中小型项目
  • 响应式编程
  • 面向对象架构

Zustand适合

  • 轻量级应用
  • 快速开发
  • 简单状态管理需求

5. 性能与最佳实践

  1. 选择正确的状态管理库
  2. 最小化状态粒度
  3. 使用选择器优化渲染
  4. 异步处理与错误边界
  5. 持久化状态
  6. 代码拆分

6. 状态管理通用模式

tsx 复制代码
 
// 通用异步Action模式
async function asyncAction<T>(
  action: () => Promise<T>, 
  onSuccess?: (result: T) => void,
  onError?: (error: Error) => void
) {
  try {
    const result = await action();
    onSuccess?.(result);
    return result;
  } catch (error) {
    onError?.(error);
    throw error;
  }
}

// 使用示例
asyncAction(
  () => fetchUserProfile(userId),
  (profile) => {
    // 成功处理
    userStore.setProfile(profile);
  },
  (error) => {
    // 错误处理
    toast.error('获取用户信息失败');
  }
);

7. 监控与调试

  • Redux DevTools
  • MobX DevTools
  • React DevTools
  • Zustand Logger Middleware

总结

状态管理是前端架构的核心,选择合适的库很重要。根据项目复杂度、团队技术栈和性能需求选择最适合的方案。

持续学习、保持开放心态! 🚀🔥

结语:React学习路径推荐

  1. 掌握基础语法和概念
  2. 深入理解Hooks
  3. 实践项目开发
  4. 学习状态管理(Redux/Mobx/Zustand)
  5. 性能优化
  6. 关注生态系统发展

持续学习资源

  • React官方文档
  • GitHub开源项目
  • 技术博客
  • 在线课程平台

加油,成为React大神! 🚀🌟

相关推荐
一直在学习的小白~5 分钟前
前端项目中创建自动化部署脚本,用于 Jenkins 触发 npm run publish 来完成远程部署
前端·自动化·jenkins
Perfect—完美21 分钟前
Vue 3 事件总线详解:构建组件间高效通信的桥梁
前端·javascript·vue.js
二川bro31 分钟前
模拟类似 DeepSeek 的对话
前端·人工智能
祈澈菇凉1 小时前
Vue 中如何实现自定义指令?
前端·javascript·vue.js
sorryhc1 小时前
解读Ant Design X API流式响应和流式渲染的原理
前端·react.js·ai 编程
1024小神2 小时前
vue/react前端项目打包的时候加上时间,防止后端扯皮
前端·vue.js·react.js
拉不动的猪2 小时前
刷刷题35(uniapp中级实际项目问题-2)
前端·javascript·面试
bigcarp2 小时前
理解langchain langgraph 官方文档示例代码中的MemorySaver
java·前端·langchain
FreeCultureBoy2 小时前
从 VS Code 的插件市场下载扩展插件
前端
前端菜鸟日常2 小时前
Webpack 和 Vite 的主要区别
前端·webpack·node.js