Reputation: 4752
Looking at the official react docs, an example is given for writing a custom hook, as below:
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
function ChatRecipientPicker() {
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>
</>
);
}
The part I'm confused about - my understanding is useEffect(...)
will trigger each time the component re-renders, which as currently described, would only happen when setRecipientID
is called. But, say another state variable is added, say, const [nameFilter, setNameFilter] = useState('')
. In this case, the component will re-render every time a user types into the filter, which I think will trigger the "connection" logic in useEffect
.
I think this would work if useEffect
took in the friendID
as the 2nd param, but being new to react I don't want to assume the official docs are not written in a resilient way, which means I'm wrong and the react plumbing somehow knows to not connect each re-render - but how?
Upvotes: 1
Views: 291
Reputation: 5036
To useEffect
you need to provide a callback that is going to be executed and, optionally, an array of values that will determine when the effect is triggered. Here you have three options:
You pass nothing - useEffect
is triggered each time components is rendered
You pass en empty array - useEffect
is triggered only once, when component is mounted
You pass an array with props and state variables - useEffect
is triggered when the component is first mounted and each time at least one of the variables changes
React does not do anything else to reduce the number of times useEffect
is called, so yes you do need to explicitly provide variables your effect depends on (friendID
in your case)
Upvotes: 1