Hook 是一個特殊的函數,它可讓你」鉤入」React state及生命週期等特性的函數。例如,useState是容許你在React函數組件中添加state的Hook。html
使用Hook其中一個目的就是要解決class中生命週期函數常常包含不相關的邏輯,但又把相關邏輯分離到幾個不一樣方法中的問題。react
若是你在編寫函數組件並意識到須要向其添加一些state,之前的作法是必須將其它轉化爲class。如今你能夠在現有的函數組件中使用Hook。數組
Hook 就是 JavaScript 函數,可是使用它們會有兩個額外的規則:性能優化
以前可能已經在 React 組件中執行過數據獲取、訂閱或者手動修改過 DOM。咱們統一把這些操做稱爲「反作用」,或者簡稱爲「做用」。函數
經過使用 Hook,你能夠把組件內相關的反作用組織在一塊兒(例如建立訂閱及取消訂閱),而不要把它們拆分到不一樣的生命週期函數裏。
Effect Hook 可讓你在函數組件中執行反作用操做。
若是你熟悉 React class 的生命週期函數,你能夠把 useEffect Hook 看作 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個函數的組合。性能
useEffect 會在每次渲染後都執行嗎?
是的,默認狀況下,它在第一次渲染以後和每次更新以後都會執行。
有的Hook是須要清理的(好比定時器),有的是不須要清理的的(好比數據獲取)。須要清理的反作用,須要返回一個函數。優化
不須要清理的effect:this
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
import React, { useState, useEffect } from 'react'; function FriendStatus(props) { const [isOnline, setIsOnline] = useState(null); useEffect(() => { function handleStatusChange(status) { setIsOnline(status.isOnline); } ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); // Specify how to clean up after this effect: return function cleanup() { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; }); if (isOnline === null) { return 'Loading...'; } return isOnline ? 'Online' : 'Offline'; }
若是某些特定值在兩次重渲染之間沒有發生變化,你能夠通知 React 跳過對 effect 的調用,只要傳遞數組做爲 useEffect 的第二個可選參數便可:eslint
useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // 僅在 count 更改時更新
若是想執行只運行一次的 effect(僅在組件掛載和卸載時執行),能夠傳遞一個空數組([])做爲第二個參數。這就告訴 React 你的 effect 不依賴於 props 或 state 中的任何值,因此它永遠都不須要重複執行。這並不屬於特殊狀況 —— 它依然遵循依賴數組的工做方式。code
推薦啓用 eslint-plugin-react-hooks 中的 exhaustive-deps 規則。此規則會在添加錯誤依賴時發出警告並給出修復建議。
更多詳細Hook API,詳見:Hook API