Skip to content

Commit

Permalink
usePrevious [nfc]: Default to null on first render.
Browse files Browse the repository at this point in the history
As Greg pointed out a few weeks ago [1], `usePrevious` has had a
"funny quirk where on the first call, it takes the "previous" value
to be the current one."

Instead, let the caller decide what the value should be on the first
render, or just have it be `null` if the caller is fine with that.

[1] zulip#4914 (comment)
  • Loading branch information
chrisbobbe authored and gnprice committed Aug 24, 2021
1 parent 58f7159 commit 3fba6a5
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/animation/AnimatedComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function AnimatedComponent(props: Props): Node {
}, [delay, targetValue, useNativeDriver]);

useEffect(() => {
if (prevVisible !== visible) {
if (prevVisible !== null && prevVisible !== visible) {
animate();
}
}, [animate, prevVisible, visible]);
Expand Down
8 changes: 4 additions & 4 deletions src/reactUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
import { useRef, useEffect } from 'react';

/**
* A Hook for the value of a prop, state, etc., from the previous
* render, or the first render if this is the first.
* A Hook for the value of a prop, state, etc., from the previous render, or
* `initValue` (defaults to `null`) if this is the first.
*
* From
* https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state,
* which says, "It’s possible that in the future React will provide a
* `usePrevious` Hook out of the box since it’s a relatively common
* use case."
*/
export function usePrevious<T>(value: T): T {
const ref = useRef<T>(value);
export function usePrevious<T>(value: T, initValue: T | null = null): T | null {
const ref = useRef<T | null>(initValue);
useEffect(() => {
ref.current = value;
});
Expand Down
2 changes: 1 addition & 1 deletion src/user-picker/UserPickerCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function UserPickerCard(props: Props) {

const prevSelectedState = usePrevious(selectedState);
useEffect(() => {
if (selectedState.length > prevSelectedState.length) {
if (prevSelectedState !== null && selectedState.length > prevSelectedState.length) {
setTimeout(() => {
listRef.current?.scrollToEnd();
});
Expand Down

0 comments on commit 3fba6a5

Please sign in to comment.