React Hook - 官方文档 - Two
2020-12-11 本文已影响0人
Suki_Yang
Hooks are functions that let you "hook into" React state and lifecycle features from function components.
Rules of Hooks
Only call Hooks at the top level.
Don't call Hooks inside loops, conditions, or nested functions.
Only call Hooks from React Functions
Don't call Hooks from regular JavaScript functions
- Call Hooks from React function components
- Call Hooks from custom Hooks
Explanation
- How does React know which state corresponds to which useState call?
React relies on the order in which Hooks are called.
State Hook
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click Me</button>
</div>
);
}
Effect Hook
The Effect Hook, useEffect, adds the ability to perform side effects from a function component.
Tips for Using Effects
Tip: Use Multiple Effects to Separate Concerns
Hooks let us split the code based on what it is doing.
Tip: Optimizing Performance by Skipping Effects
import React, { useState, useEffect } from 'react';
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);
//The effect cleanup phase happens after every re-render, and not just once during unmounting
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
if (isOnline === null) {
return 'Loading...';
}
return (
<div>
<p>{isOnline ? 'Online' : 'Offline'}</p>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
Build Your Own Hooks
Building your own Hooks lets you extract component logic into reusable functions.
A custom Hook is a JavaScript function whose name starts with "use" and that may call other Hooks.
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);
};
}, [props.friend.id]);
return 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>
);
}
const friendList = [
{ id: 1, name: 'Phoebe' },
{ id: 2, name: 'Rachel' },
{ id: 3, name: 'Ross' }
];
function ChatRecipientPicker() {
//Pass information Between Hooks
const [recipientID, setRecipientID] = useState(1);
const isRecipientOnline = useFriendStatus(recipientID);
return (
<>
<Circle color={isRecipientOnline ? 'green' : 'red'} />
<select
value={recipientID}
onChange={e => setRecipientID(Number(e.target.value))}
>
{friendList.map(friend => (
<option key={friend.id} value={friend.id}>
{friend.name}
</option>
))}
</select>
</>
);
}