Skip to content

Commit

Permalink
Animated: Stabilize allowlist in useAnimatedPropsMemo (facebook#4…
Browse files Browse the repository at this point in the history
…9140)

Summary:
Pull Request resolved: facebook#49140

Similar to the change made in `useAnimatedProps`, except for `useAnimatedPropsMemo`. (This is just split out to make the changes easier to review.)

Changelog:
[Internal]

Reviewed By: javache

Differential Revision: D69058338

fbshipit-source-id: 033853673d8fe1442b37bb0c0adc7cb22557c334
  • Loading branch information
yungsters authored and facebook-github-bot committed Feb 4, 2025
1 parent 5d4907d commit bc4dee9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import AnimatedValue from '../../../../Libraries/Animated/nodes/AnimatedValue';
import {
areCompositeKeysEqual,
createCompositeKeyForProps,
} from '../useAnimatedPropsMemo';
} from '../createAnimatedPropsMemoHook';

describe('createCompositeKeyForProps', () => {
describe('with allowlist', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import AnimatedValue from '../../../Libraries/Animated/nodes/AnimatedValue';
import {isPublicInstance as isFabricPublicInstance} from '../../../Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils';
import useRefEffect from '../../../Libraries/Utilities/useRefEffect';
import * as ReactNativeFeatureFlags from '../featureflags/ReactNativeFeatureFlags';
import {createAnimatedPropsMemoHook} from './createAnimatedPropsMemoHook';
import NativeAnimatedHelper from './NativeAnimatedHelper';
import {useAnimatedPropsMemo} from './useAnimatedPropsMemo';
import {
useCallback,
useEffect,
Expand Down Expand Up @@ -49,6 +49,8 @@ type AnimatedValueListeners = Array<{
export default function createAnimatedPropsHook(
allowlist: ?AnimatedPropsAllowlist,
): AnimatedPropsHook {
const useAnimatedPropsMemo = createAnimatedPropsMemoHook(allowlist);

return function useAnimatedProps<TProps: {...}, TInstance>(
props: TProps,
): [ReducedProps<TProps>, CallbackRef<TInstance | null>] {
Expand All @@ -58,7 +60,7 @@ export default function createAnimatedPropsHook(

const node = useAnimatedPropsMemo(
() => new AnimatedProps(props, () => onUpdateRef.current?.(), allowlist),
[allowlist, props],
props,
);

const useNativePropsInFabric =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,43 +48,50 @@ type $ReadOnlyCompositeKeyComponent =
| $ReadOnlyArray<$ReadOnlyCompositeKeyComponent | null>
| $ReadOnly<{[string]: $ReadOnlyCompositeKeyComponent}>;

type AnimatedPropsMemoHook = (
() => AnimatedProps,
props: $ReadOnly<{[string]: mixed}>,
) => AnimatedProps;

/**
* A hook that returns an `AnimatedProps` object that is memoized based on the
* subset of `props` that are instances of `AnimatedNode` or `AnimatedEvent`.
* Creates a hook that returns an `AnimatedProps` object that is memoized based
* on the subset of `props` that are instances of `AnimatedNode` or
* `AnimatedEvent`.
*/
export function useAnimatedPropsMemo(
create: () => AnimatedProps,
// TODO: Make this two separate arguments after the experiment is over. This
// is only an array-like structure to make it easier to experiment with this
// and `useMemo`.
[allowlist, props]: [?AnimatedPropsAllowlist, {[string]: mixed}],
): AnimatedProps {
const compositeKey = useMemo(
() => createCompositeKeyForProps(props, allowlist),
[allowlist, props],
);

const [state, setState] = useState<{
allowlist: ?AnimatedPropsAllowlist,
compositeKey: $ReadOnlyCompositeKey | null,
value: AnimatedProps,
}>(() => ({
allowlist,
compositeKey,
value: create(),
}));
export function createAnimatedPropsMemoHook(
allowlist: ?AnimatedPropsAllowlist,
): AnimatedPropsMemoHook {
return function useAnimatedPropsMemo(
create: () => AnimatedProps,
props: $ReadOnly<{[string]: mixed}>,
): AnimatedProps {
const compositeKey = useMemo(
() => createCompositeKeyForProps(props, allowlist),
[props],
);

if (
state.allowlist !== allowlist ||
!areCompositeKeysEqual(state.compositeKey, compositeKey)
) {
setState({
const [state, setState] = useState<{
allowlist: ?AnimatedPropsAllowlist,
compositeKey: $ReadOnlyCompositeKey | null,
value: AnimatedProps,
}>(() => ({
allowlist,
compositeKey,
value: create(),
});
}
return state.value;
}));

if (
state.allowlist !== allowlist ||
!areCompositeKeysEqual(state.compositeKey, compositeKey)
) {
setState({
allowlist,
compositeKey,
value: create(),
});
}
return state.value;
};
}

/**
Expand Down

0 comments on commit bc4dee9

Please sign in to comment.