轉載於免費視頻網 www.rails365.netreact
Hooks
是JavaScript
函數,但在使用它們時須要遵循兩個規則。咱們提供了一個linter
插件來自動執行這些規則:git
不要在循環,條件或嵌套函數中調用Hook。 相反,老是在React
函數的頂層使用Hooks
。經過遵循此規則,能夠確保每次組件呈現時都以相同的順序 調用Hook
。這就是容許React
在多個useState
和useEffect
調用之間正確保留Hook
狀態的緣由。 (若是你很好奇, 咱們將在下面深刻解釋。)github
React Functions
調用Hooks
不要從常規JavaScript
函數中調用Hook
。 相反,你能夠:shell
經過遵循此規則,能夠確保組件中的全部有狀態邏輯從其源代碼中清晰可見。npm
咱們發佈了一個名爲eslint-plugin-react-hooks的ESLint插件,它強制執行這兩個規則。若是您想嘗試,能夠將此插件添加到項目中:數組
npm install eslint-plugin-react-hooks@next
複製代碼
// Your ESLint configuration
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error"
}
}
複製代碼
未來,有打算默認將此插件包含在Create React App
和相似的工具包中。函數
以前有說過,一個組件能夠配置多個狀態變量或者效果鉤子:工具
function Form() {
// 1. Use the name state variable
const [name, setName] = useState('Mary');
// 2. Use an effect for persisting the form
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
// 3. Use the surname state variable
const [surname, setSurname] = useState('Poppins');
// 4. Use an effect for updating the title
useEffect(function updateTitle() {
document.title = name + ' ' + surname;
});
// ...
}
複製代碼
那麼React
如何知道哪一個狀態對應於哪一個useState
調用?答案是 React
依賴於調用Hooks
的順序。 咱們的示例有效,由於Hook調用的順序在每一個渲染上都是相同的:ui
// ------------
// First render
// ------------
useState('Mary') // 1. 初始化`name`狀態變量爲 'Mary'
useEffect(persistForm) // 2. 添加一個效果
useState('Poppins') // 3. 初始化`surname`狀態變量爲 'Poppins'
useEffect(updateTitle) // 4. 添加一個效果
// -------------
// Second render
// -------------
useState('Mary') // 1. 讀取`name`狀態變量 (參數被忽略)
useEffect(persistForm) // 2. 替換以前的效果
useState('Poppins') // 3. 相似於上面的`name state`
useEffect(updateTitle) // 4. 也是替換成如今的這個
// ...
複製代碼
只要Hook
調用的順序在渲染之間是相同的,React
就能夠將一些本地狀態與它們中的每個相關聯。可是若是咱們在條件中放置Hook調用(例如,persistForm效果)會發生什麼?spa
useState('Mary') // 1. 讀取`name`狀態變量 (參數被忽略)
// useEffect(persistForm) // 🔴這個Hook被幹掉了
useState('Poppins') // 🔴 2 (可是以前是第三步). 讀取`surname`狀態變量失敗
useEffect(updateTitle) // 🔴 3 (可是以前是第四步). 替換`effect`失敗
複製代碼
React
不知道第二次useState Hook
調用返回什麼。 React
指望此組件中的第二個Hook
調用對應於persistForm
效果,就像在前一個渲染中同樣,但它再也不存在。從那時起,在咱們跳過的那個以後的每一個下一個Hook
調用也會移動一個,致使錯誤。
這就是爲何咱們須要在組件頂層調用Hook
的緣由。 若是咱們想要有條件地運行一個效果,咱們能夠把這個條件放在咱們的Hook
中:
useEffect(function persistForm() {
// 👍 We're not breaking the first rule anymore
if (name !== '') {
localStorage.setItem('formData', name);
}
});
複製代碼
請注意,若是使用提供的lint規則,則無需擔憂此問題。 可是如今你也知道爲何Hooks
以這種方式工做,以及規則阻止了哪些問題。