Hooks有不少種,好比react
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div>
);
}
複製代碼
這個例子上一篇有提到過,這裏useState就是一個Hook(待會會討論什麼是Hook)。咱們在函數內部調用這個Hook,給組件添加了一個內部state,在re-render的時候React會保留這個state。數組
useState的參數:ide
useState的返回值:返回了2個東西函數
一個組件裏能夠聲明多個state變量學習
function ExampleWithManyStates() {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}
複製代碼
Hook就是一個鉤子函數,用Hook就能從函數組件裏hook到React state和生命週期。ui
Hook不能在class裏使用spa
React提供了許多內置Hook,你也能夠寫自定義Hook。咱們先學習內置Hook插件
Effect Hook, useEffect
,給函數組件提供了執行反作用的能力。useEffect的用處和class組件裏的componentDidMount
, componentDidUpdate
, and componentWillUnmount
同樣,可是不像class組件裏的3個API,useEffect被整合成了一個單獨的API。code
舉個例子,下面這個組件在React更新DOM後會更改文檔標題component
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div>
);
}
複製代碼
useEffect的參數就是反作用函數,這個函數在React Update以後執行。
useEffect要在組件內部定義,這樣才能獲取到組件的props和state。
默認狀況下,react在每次render的過程當中(包括初次渲染)都會執行反作用函數。
Effect Hook接收的反作用函數的返回值能夠是一個函數,這個函數告訴React如何清理這些反作用。
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
複製代碼
return的函數將在2個時刻調用:
相似useState,一個組件能夠定義多個effect
function FriendStatusWithCounter(props) {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
// ...
複製代碼
有2點
前面介紹了一個調用useState和useEffect Hooks的FriendStatus組件來訂閱朋友的在線狀態。假設咱們還但願在另外一個組件中重用此訂閱邏輯。
首先,咱們將這個邏輯提取到一個名爲useFriendStatus的自定義Hook中:
import React, { useState, useEffect } from 'react';
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
複製代碼
useFriendStatus將friendID做爲參數,返回isOnline。
如今咱們能夠從兩個組件中使用它:
function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
複製代碼
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}> {props.friend.name} </li>
);
}
複製代碼
useSomething
這種命名約定能在使用Hook的時候幫助linter插件定位bug。useContext能在不引入嵌套的狀況下訂閱React上下文
function Example() {
const locale = useContext(LocaleContext);
const theme = useContext(ThemeContext);
// ...
}
複製代碼
useReducer能用reduce管理複雜組件的本地狀態
function Todos() {
const [todos, dispatch] = useReducer(todosReducer);
// ...
複製代碼