React 是一个用于构建用户界面的 JavaScript 库。它以声明式的方式让开发者可以轻松构建复杂且交互性强的 UI。要真正驾驭 React,深入理解其核心 API 至关重要。这些 API 是构建组件、管理状态、处理副作用、优化性能以及与其他系统交互的基础。本文将对 React 的核心 API 进行深度解读,涵盖从组件定义到高级优化等各个方面。
核心思想:React 核心 API 围绕组件化、声明式UI、单向数据流和性能优化展开,通过 Hooks 极大地简化了函数组件的状态管理和副作用处理,使复杂逻辑更易组织和复用。
一、React 的核心模块与入口 React 库被拆分为两个主要模块:react 和 react-dom。
react : 包含构建组件和定义其行为所需的核心 API(如 Component, useState, useEffect, createContext 等)。
react-dom : 提供与 DOM 交互的特定方法(如 render, createRoot 等),用于将 React 组件渲染到浏览器环境。
react-dom 主要 API1. createRoot(container) (React 18+) 用途 : 用于在客户端首次渲染 React 应用,是 React 18 引入的新的根 API,支持并发特性如 Concurrent Mode 和 Suspense。
参数 :
container: 一个 DOM 元素,React 将在该元素内部渲染您的组件。
返回值 : 一个根对象 (Root)。
示例 :
1 2 3 4 5 6 7 8 9 10 import React from 'react' ;import { createRoot } from 'react-dom/client' ; import App from './App' ;const container = document .getElementById ('root' );const root = createRoot (container); root.render (<App /> );
2. render(element, container, [callback]) (React 17 及以下) 用途 : 将一个 React 元素渲染到提供了的 container DOM 节点中,并返回对组件实例的引用(对于类组件)。
参数 :
element: 要渲染的 React 元素(通常是 JSX)。
container: DOM 元素,React 将在其内部渲染内容。
callback (可选): 在组件渲染或更新后执行的回调函数。
示例 :
1 2 3 4 5 6 7 8 9 10 import React from 'react' ;import ReactDOM from 'react-dom' ; import App from './App' ;ReactDOM .render ( <React.StrictMode > <App /> </React.StrictMode > , document .getElementById ('root' ) );
3. unmountComponentAtNode(container) (React 17 及以下) 用途 : 从 DOM 中移除已挂载的 React 组件,清理其事件处理器和状态。
示例 :
1 ReactDOM .unmountComponentAtNode (document .getElementById ('root' ));
二、组件定义 API React 主要提供两种组件定义方式:函数组件 (Function Components) 和类组件 (Class Components)。随着 Hooks 的引入,函数组件已成为主流。
1. 函数组件 (Function Components) 定义 : 普通的 JavaScript 函数,接收 props 对象作为参数,并返回一个 React 元素(通常是 JSX)。
特点 :
无状态 (在 Hooks 出现之前)。
更简洁、易于测试。
配合 Hooks 使用,可以拥有状态和生命周期等功能。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import React from 'react' ;function Greeting (props ) { return <h1 > Hello, {props.name}!</h1 > ; } const Farewell = (props ) => { return <p > Goodbye, {props.name}.</p > ; }; const Profile = ({ name, age } ) => { return ( <div > <p > Name: {name}</p > <p > Age: {age}</p > </div > ); };
2. 类组件 (Class Components) 定义 : ES6 类,继承自 React.Component,且必须实现 render() 方法。
特点 :
拥有自身的状态 (state)。
可以通过生命周期方法 (componentDidMount, componentDidUpdate, componentWillUnmount 等) 响应组件的生命周期事件。
在 React 16.8 (Hooks 引入) 之后,不建议在新项目中使用,但仍需了解其概念。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import React , { Component } from 'react' ; class Timer extends Component { constructor (props ) { super (props); this .state = { count : 0 }; } componentDidMount ( ) { this .timerID = setInterval (() => this .tick (), 1000 ); } componentWillUnmount ( ) { clearInterval (this .timerID ); } tick ( ) { this .setState (prevState => ({ count : prevState.count + 1 })); } render ( ) { return <p > Count: {this.state.count}</p > ; } }
三、React Hooks API (React 16.8+) Hooks 是函数组件的核心。它们允许你在不编写 class 的情况下使用 state 和其他 React 特性。
1. useState 用途 : 为函数组件添加状态。
语法 : const [state, setState] = useState(initialState);
参数 :
initialState: 状态的初始值。可以是任意类型,也可以是一个函数(该函数只会在首次渲染时执行,用于惰性初始化)。
返回值 : 一个数组,包含:
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import React , { useState } from 'react' ;function Counter ( ) { const [count, setCount] = useState (0 ); const [message, setMessage] = useState ('' ); const [user, setUser] = useState ({ name : 'Guest' , age : 0 }); const increment = ( ) => { setCount (prevCount => prevCount + 1 ); }; const updateUserName = (newName ) => { setUser (prevUser => ({ ...prevUser, name : newName })); }; return ( <div > <p > Count: {count}</p > <button onClick ={increment} > Increment</button > <p > User Name: {user.name}</p > <button onClick ={() => updateUserName('Alice')}>Set Alice</button > <input type ="text" value ={message} onChange ={(e) => setMessage(e.target.value)} /> <p > Message: {message}</p > </div > ); }
2. useEffect 用途 : 在函数组件中执行副作用操作(数据获取、订阅事件、手动修改 DOM、清理等)。它替代了类组件的 componentDidMount, componentDidUpdate, componentWillUnmount。
语法 : useEffect(setup, [dependencies]);
参数 :
setup: 包含副作用逻辑的函数。此函数可以返回一个清理函数(可选)。
dependencies (可选数组): 一个依赖项数组。
如果省略,useEffect 每次渲染后都会执行。
如果为空数组 [],useEffect 只会在组件挂载时执行一次,并在组件卸载时执行清理函数(类似于 componentDidMount 和 componentWillUnmount)。
如果包含依赖项,useEffect 会在依赖项发生变化时重新执行。
返回值 : 无。
清理函数 : useEffect 返回的函数会在下次 useEffect 执行前或组件卸载时执行,用于清理上次作用(如取消订阅、清除定时器)。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 import React , { useState, useEffect } from 'react' ;function DataFetcher ({ userId } ) { const [data, setData] = useState (null ); const [loading, setLoading] = useState (true ); const [error, setError] = useState (null ); useEffect (() => { console .log (`Fetching data for userId: ${userId} ` ); setLoading (true ); setError (null ); setData (null ); const abortController = new AbortController (); const signal = abortController.signal ; fetch (`https://jsonplaceholder.typicode.com/users/${userId} ` , { signal }) .then (response => { if (!response.ok ) { throw new Error ('Network response was not ok' ); } return response.json (); }) .then (json => { setData (json); }) .catch (err => { if (err.name === 'AbortError' ) { console .log ('Fetch aborted' ); } else { setError (err); } }) .finally (() => { setLoading (false ); }); return () => { console .log (`Cleaning up for userId: ${userId} ` ); abortController.abort (); }; }, [userId]); if (loading) return <div > Loading user data...</div > ; if (error) return <div > Error: {error.message}</div > ; if (!data) return <div > No data found.</div > ; return ( <div > <h2 > User Profile</h2 > <p > Name: {data.name}</p > <p > Email: {data.email}</p > </div > ); }
3. useContext 用途 : 订阅 React Context 的值。这使得组件可以直接访问组件树中更高层组件提供的 Context 值,避免了 props 层层传递。
语法 : const value = useContext(MyContext);
参数 :
MyContext: 由 React.createContext() 创建的 Context 对象。
返回值 : Context 对象的当前值。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import React , { createContext, useContext, useState } from 'react' ;const ThemeContext = createContext ('light' );function ThemeProvider ({ children } ) { const [theme, setTheme] = useState ('light' ); const toggleTheme = ( ) => setTheme (t => (t === 'light' ? 'dark' : 'light' )); const contextValue = { theme, toggleTheme }; return ( <ThemeContext.Provider value ={contextValue} > {children} </ThemeContext.Provider > ); } function ThemedButton ( ) { const { theme, toggleTheme } = useContext (ThemeContext ); return ( <button className ={theme} onClick ={toggleTheme} > Current theme: {theme} </button > ); } function App ( ) { return ( <ThemeProvider > <div > <h1 > My App</h1 > <ThemedButton /> <p > Some other content...</p > </div > </ThemeProvider > ); }
4. useRef 用途 : 创建一个可变的 ref 对象,其 .current 属性可以在组件的整个生命周期中保存可变值,而不会导致重新渲染。最常见的用途是访问 DOM 元素。
语法 : const refContainer = useRef(initialValue);
参数 :
initialValue: ref 对象 .current 属性的初始值。
返回值 : 一个具有 current 属性的普通 JavaScript 对象。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import React , { useRef, useEffect } from 'react' ;function FocusInput ( ) { const inputRef = useRef (null ); useEffect (() => { if (inputRef.current ) { inputRef.current .focus (); } }, []); const handleClick = ( ) => { if (inputRef.current ) { alert (`Input value: ${inputRef.current.value} ` ); } }; return ( <div > <input type ="text" ref ={inputRef} /> {/* 将 ref 绑定到 DOM 元素 */} <button onClick ={handleClick} > Show Input Value</button > </div > ); }
5. useReducer 用途 : useState 的替代方案,用于管理更复杂的 state 逻辑,例如涉及多个子值的 state,或者下一个 state 依赖于前一个 state。它与 Redux 的 reducer 概念相似。
语法 : const [state, dispatch] = useReducer(reducer, initialArg, init);
参数 :
reducer(state, action): 一个纯函数,根据 state 和 action 计算新的 state。
initialArg: 初始状态。
init (可选): 一个惰性初始化函数,如果提供,则 initialArg 将作为其参数,其返回值作为初始状态。
返回值 : 一个数组,包含:
当前状态值。
一个 dispatch 函数,用于派发 action 来更新 state。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import React , { useReducer } from 'react' ;const initialState = { count : 0 };function reducer (state, action ) { switch (action.type ) { case 'increment' : return { count : state.count + 1 }; case 'decrement' : return { count : state.count - 1 }; case 'reset' : return initialState; case 'set' : return { count : action.payload }; default : throw new Error (); } } function CounterWithReducer ( ) { const [state, dispatch] = useReducer (reducer, initialState); return ( <div > <p > Count: {state.count}</p > <button onClick ={() => dispatch({ type: 'increment' })}>Increment</button > <button onClick ={() => dispatch({ type: 'decrement' })}>Decrement</button > <button onClick ={() => dispatch({ type: 'reset' })}>Reset</button > <button onClick ={() => dispatch({ type: 'set', payload: 100 })}>Set to 100</button > </div > ); }
6. useCallback 用途 : 记住(memoize)一个回调函数。当把回调函数作为 prop 传递给优化过的子组件时,或者作为 useEffect 的依赖项时,useCallback 可以避免不必要的重新创建函数实例,从而防止子组件不必要的重新渲染。
语法 : const memoizedCallback = useCallback(callback, [dependencies]);
参数 :
callback: 要记住的函数。
dependencies (数组): 依赖项数组。只有当依赖项发生变化时,callback 才会重新创建。
返回值 : 记忆化的函数。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import React , { useState, useCallback, memo } from 'react' ;const ChildComponent = memo (({ onClick, value } ) => { console .log ('ChildComponent rendered' ); return ( <button onClick ={onClick} > Click me ({value}) </button > ); }); function ParentComponent ( ) { const [count, setCount] = useState (0 ); const [name, setName] = useState ('Alice' ); const handleClick = useCallback (() => { setCount (prevCount => prevCount + 1 ); }, []); return ( <div > <p > Parent Count: {count}</p > <ChildComponent onClick ={handleClick} value ={count} /> <input type ="text" value ={name} onChange ={(e) => setName(e.target.value)} /> <p > Parent Name: {name}</p > </div > ); }
7. useMemo 用途 : 记住(memoize)一个计算结果。它会在依赖项不变的情况下,避免重复执行昂贵的计算。
语法 : const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
参数 :
computeExpensiveValue: 一个在渲染期间执行的函数,返回要记住的值。
dependencies (数组): 依赖项数组。只有当依赖项发生变化时,函数才会重新执行。
返回值 : 记忆化的计算结果。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import React , { useState, useMemo } from 'react' ;function calculateFactorial (n ) { console .log (`Calculating factorial for ${n} ...` ); if (n < 0 ) return -1 ; if (n === 0 ) return 1 ; let result = 1 ; for (let i = 1 ; i <= n; i++) { result *= i; } return result; } function FactorialCalculator ( ) { const [number, setNumber] = useState (1 ); const [incrementor, setIncrementor] = useState (0 ); const factorial = useMemo (() => calculateFactorial (number), [number]); return ( <div > <p > Factorial of {number} is: {factorial}</p > <button onClick ={() => setNumber(number + 1)}>Increment Number ({number})</button > <p > Incrementor: {incrementor}</p > <button onClick ={() => setIncrementor(incrementor + 1)}>Increment Incrementor ({incrementor})</button > </div > ); }
8. useImperativeHandle 用途 : 允许在 useRef 配合 forwardRef 使用时,自定义暴露给父组件的实例值,从而限制父组件可以访问的子组件内部功能。
语法 : useImperativeHandle(ref, createHandle, [dependencies]);
参数 :
ref: 由 React.forwardRef 提供的 ref 对象。
createHandle: 一个函数,返回父组件将通过 ref.current 访问到的值。
dependencies (数组): 当依赖项变化时,createHandle 会重新执行。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import React , { useRef, useImperativeHandle, forwardRef } from 'react' ;const SmallInput = forwardRef (({ label }, ref ) => { const inputEl = useRef (null ); useImperativeHandle (ref, () => ({ focusInput : () => { inputEl.current .focus (); }, clearInput : () => { inputEl.current .value = '' ; }, getInputValue : () => inputEl.current .value })); return ( <div > <label > {label}: </label > <input type ="text" ref ={inputEl} /> </div > ); }); function ParentComponentWithInputHandle ( ) { const inputRef = useRef (null ); const handleFocus = ( ) => { if (inputRef.current ) { inputRef.current .focusInput (); } }; const handleClear = ( ) => { if (inputRef.current ) { inputRef.current .clearInput (); } }; const handleAlertValue = ( ) => { if (inputRef.current ) { alert (`Input value is: ${inputRef.current.getInputValue()} ` ); } }; return ( <div > <SmallInput label ="My text" ref ={inputRef} /> <button onClick ={handleFocus} > Focus Input</button > <button onClick ={handleClear} > Clear Input</button > <button onClick ={handleAlertValue} > Alert Value</button > </div > ); }
9. useLayoutEffect 用途 : 与 useEffect 类似,但它在所有 DOM 变更后同步执行,浏览器在绘制前。适用于需要测量 DOM 布局(如滚动位置、元素尺寸)或执行与 DOM 视觉渲染紧密相关的副作用。
语法 : useLayoutEffect(setup, [dependencies]);
特性 :
它的回调函数会在浏览器执行绘制之前执行,因此可以同步修改 DOM 布局。
会阻塞浏览器的绘制,如果执行时间过长,可能导致性能问题。
通常情况下,优先使用 useEffect,只有当需要同步操作 DOM 并且这会影响用户可见的布局时才使用 useLayoutEffect。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import React , { useState, useRef, useLayoutEffect } from 'react' ;function Tooltip ({ children, position } ) { const [tooltipStyle, setTooltipStyle] = useState ({}); const tooltipRef = useRef (null ); useLayoutEffect (() => { if (tooltipRef.current ) { const { width, height } = tooltipRef.current .getBoundingClientRect (); if (position === 'top' ) { setTooltipStyle ({ transform : `translateY(-${height + 10 } px)` }); } else if (position === 'left' ) { setTooltipStyle ({ transform : `translateX(-${width + 10 } px)` }); } } }, [position]); return ( <div style ={{ position: 'relative ', display: 'inline-block ' }}> {children} <div ref ={tooltipRef} style ={{ ...tooltipStyle , position: 'absolute ', background: 'black ', color: 'white ' }}> I'm a tooltip! </div > </div > ); }
10. useDebugValue 用途 : 用于在 React DevTools 中显示自定义 Hook 的标签。它不影响代码逻辑。
语法 : useDebugValue(value, [format])
参数 :
value: 要显示的值。
format (可选): 一个函数,用于格式化 value,只在 DevTools 面板打开时执行,避免性能开销。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import React , { useState, useDebugValue } from 'react' ;function useOnlineStatus ( ) { const [isOnline, setIsOnline] = useState (true ); useDebugValue (isOnline, value => value ? 'Online' : 'Offline' ); React .useEffect (() => { const handleOnline = ( ) => setIsOnline (true ); const handleOffline = ( ) => setIsOnline (false ); window .addEventListener ('online' , handleOnline); window .addEventListener ('offline' , handleOffline); return () => { window .removeEventListener ('online' , handleOnline); window .removeEventListener ('offline' , handleOffline); }; }, []); return isOnline; } function StatusBar ( ) { const isOnline = useOnlineStatus (); return <h1 > {isOnline ? '✅ Online' : '❌ Offline'}</h1 > ; }
四、其他核心 API 1. ReactDOM.createPortal(child, container) 用途 : 将子节点渲染到存在于父组件 DOM 层级之外的 DOM 节点。这在处理模态框 (Modals)、浮窗 (Tooltips)、加载指示器等需要脱离父元素样式或溢出限制的场景非常有用。
参数 :
child: 可以是任何可渲染的 React 子元素 (例如 JSX)。
container: 一个 DOM 元素,React 会将 child 挂载到这个 DOM 元素下。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import React from 'react' ;import { createPortal } from 'react-dom' ;const modalRoot = document .getElementById ('modal-root' ); function Modal ({ children, isOpen, onClose } ) { if (!isOpen) return null ; return createPortal ( <div style ={{ position: 'fixed ', top: 0 , left: 0 , right: 0 , bottom: 0 , backgroundColor: 'rgba (0 ,0 ,0 ,0.5 )', display: 'flex ', alignItems: 'center ', justifyContent: 'center ' }}> <div style ={{ background: 'white ', padding: '20px ', borderRadius: '5px ' }}> {children} <button onClick ={onClose} > Close Modal</button > </div > </div > , modalRoot ); } function App ( ) { const [showModal, setShowModal] = React .useState (false ); return ( <div > <h1 > My App</h1 > <button onClick ={() => setShowModal(true)}>Open Modal</button > <Modal isOpen ={showModal} onClose ={() => setShowModal(false)}> <h2 > This is a modal!</h2 > <p > It's rendered outside the main app DOM tree.</p > </Modal > </div > ); }
2. React.memo(Component, [arePropsEqual]) 用途 : 是一种高阶组件 (HOC),用于优化函数组件的性能。它会记住组件的渲染结果,如果 props 没有改变,则跳过重新渲染该组件。
参数 :
Component: 要进行性能优化的函数组件。
arePropsEqual (可选): 一个函数,用于自定义比较 props。如果返回 true,表示 props 相同,跳过重新渲染;否则重新渲染。默认是浅比较。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import React , { memo, useState } from 'react' ;const ExpensiveComponentUnoptimized = ({ count, name } ) => { console .log ('ExpensiveComponentUnoptimized rendered' ); return <p > Count: {count}, Name: {name}</p > ; }; const ExpensiveComponent = memo (({ count, name } ) => { console .log ('ExpensiveComponent (memoized) rendered' ); return <p > Count: {count}, Name: {name}</p > ; }); function ParentComponentOptimize ( ) { const [parentCount, setParentCount] = useState (0 ); const [parentName, setParentName] = useState ('World' ); return ( <div > <h1 > Parent Component</h1 > <button onClick ={() => setParentCount(parentCount + 1)}> Increment Parent Count ({parentCount}) </button > <button onClick ={() => setParentName(parentName === 'World' ? 'React' : 'World')}> Change Parent Name ({parentName}) </button > {/* 每次 ParentComponentOptimize 渲染,都会重新渲染 */} <ExpensiveComponentUnoptimized count ={parentCount} name ={parentName} /> {/* 仅当 props (count, name) 发生变化时才重新渲染 */} <ExpensiveComponent count ={parentCount} name ={parentName} /> </div > ); }
3. React.forwardRef(render) 用途 : 允许函数组件接收一个 ref,并将其向下转发给子组件内部的 DOM 节点或另一个 React 组件。
参数 :
render: 一个渲染函数,接收 props 和 ref 作为参数。
示例 : (见 useImperativeHandle 示例,SmallInput 组件就是用 forwardRef 包裹的)
4. React.createContext(defaultValue) 用途 : 创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件时,它会从组件树中离这个组件最近的 Provider 获取当前 Context 值。
参数 :
defaultValue: 只有当组件没有对应的 Provider 时才会被使用。如果提供了 Provider,defaultValue 不起作用。
返回值 : 一个 Context 对象,包含 Provider 和 Consumer 组件。
示例 : (见 useContext 示例)
5. React.lazy(loadComponent) + React.Suspense 用途 :
React.lazy: 允许你以动态导入(import())的方式定义一个按需加载的组件。
React.Suspense: 允许在子组件(或组件树中的某个地方)完成异步加载时,展示一个回退 (fallback) UI。
这对于代码分割和优化初始加载性能非常有用。
语法 :
const MyLazyComponent = React.lazy(() => import('./MyComponent'));
<Suspense fallback={<p>Loading...</p>}> ... </Suspense>
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import React , { Suspense } from 'react' ;const LazyLoadedComponent = React .lazy (() => import ('./LazyLoadedComponent' ));function AppWithLazyLoading ( ) { const [showLazy, setShowLazy] = React .useState (false ); return ( <div > <h1 > Main App</h1 > <button onClick ={() => setShowLazy(true)}>Load Lazy Component</button > {showLazy && ( // Suspense 边界,当 LazyLoadedComponent 正在加载时,显示 fallback <Suspense fallback ={ <div > Loading lazy component...</div > }> <LazyLoadedComponent /> </Suspense > )} </div > ); }
6. React.StrictMode 用途 : 一个用于突出显示应用中潜在问题的工具。它不会渲染任何可见 UI,但会为其后代激活额外的检查和警告。
特性 :
在开发模式下,它会对以下行为发出警告:
不安全的生命周期方法。
使用过时的字符串 ref API。
使用了废弃的 findDOMNode 方法。
检测意外的副作用(双重调用 render 函数、useEffect 的 setup/cleanup 函数)。
遗留 Context API。
不会对生产环境产生影响。
示例 :
1 2 3 4 5 6 7 8 9 10 11 import React from 'react' ;import { createRoot } from 'react-dom/client' ;import App from './App' ;const container = document .getElementById ('root' );const root = createRoot (container);root.render ( <React.StrictMode > <App /> </React.StrictMode > );
五、总结与展望 React 的核心 API 旨在提供一套强大而灵活的工具集,以构建高性能和可维护的 UI。从基础的组件定义到现代的 Hooks,再到高级的 Portal、Memo 和 Suspense,React 持续演进,不断提升开发者的体验和应用的性能。
函数组件 + Hooks : 已经成为 React 开发的首选范式,极大地简化了状态管理和副作用处理。
Virtual DOM : 保证了高效的 UI 更新。
声明式编程 : 让 UI 逻辑更清晰、更易于理解。
组件化 : 促进了代码复用和可维护性。
深入理解并熟练运用这些 API,是成为一名高效 React 开发者的关键。React 强大的生态系统和不断创新的特性,将继续为前端开发带来更多可能性。