副作用与 useEffect
渲染是纯计算(同样的 props/state 必须得到同样的界面),但真实应用要做“副作用”:改页面标题、发请求、起定时器、监听窗口——这些与渲染结果无关的“对外作用”就是 useEffect 的管辖区。
useEffect 在每次渲染“画完之后”执行,且默认每次渲染都执行。读 DOM、加监听、发请求都放这里——因为此时真实 DOM 已经更新完毕。
- 副作用 = 与渲染无关的对外操作:请求、定时器、订阅、document.title
- useEffect 在渲染提交到屏幕之后才执行,不会阻塞画面
- 默认每次渲染后都跑,靠依赖数组控制频率
HTML
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>useEffect</title> <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> const { useState, useEffect } = React; function App() { const [count, setCount] = useState(0); // 副作用:改页面标题(每次渲染后都会跑) useEffect(() => { document.title = '点击了 ' + count + ' 次'; console.log('渲染完成,count =', count); }); return ( <div style={{ padding: 16 }}> <p>看看浏览器标签页的标题</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); } ReactDOM.createRoot(document.getElementById('root')).render(<App />); </script> </body> </html>
本节要点useEffect 专管副作用:渲染完成后执行;默认每次渲染都跑,不传依赖数组就是这个效果。




