Skip to content

Commit

Permalink
refactor: added useAnimatedValue hook for internal usage (#97)
Browse files Browse the repository at this point in the history
## 📜 Description

Added `useAnimatedValue` hook for storing `Animated.Value`. For internal
usage only.

## 💡 Motivation and Context

Variant with:

```ts
const value = useRef(new Animated.Value(0)).current;
```

Is not good, since `new Animated.Value(0)` will be recreated on every
re-render (it will not have direct pointers so it will be collected by
GC, but it's additional job for memory allocation and further
deallocation which is not needed in the fact).

Variant with:

```ts
const [value] = useState(() => new Animated.Value(0));
```

May also be a not good alternative, since the function inside of
`useState` will be re-created on every re-render.

So the variant with `useAnimatedValue` hook seems a best candidate for
that, since it will create a value only once (on initial render).

## 📢 Changelog

### JS
- added `useAnimatedValue` hook for internal usage;

## 🤔 How Has This Been Tested?

Tested on iPhone 13 Pro (iOS 15.0) - works as before.

## 📝 Checklist

- [x] CI successfully passed
  • Loading branch information
kirillzyusko authored Nov 6, 2022
1 parent 0e5ed8e commit 6ea3499
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/animated.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React, { useMemo, useRef } from 'react';
import React, { useMemo } from 'react';
import { Animated, Platform, StyleSheet, ViewStyle } from 'react-native';
import Reanimated, { useSharedValue } from 'react-native-reanimated';

import { KeyboardContext } from './context';
import { useAnimatedKeyboardHandler, useSharedHandlers } from './internal';
import {
useAnimatedKeyboardHandler,
useSharedHandlers,
useAnimatedValue,
} from './internal';
import { KeyboardControllerView } from './native';

import type {
Expand Down Expand Up @@ -52,8 +56,8 @@ export const KeyboardProvider = ({
statusBarTranslucent,
}: KeyboardProviderProps) => {
// animated values
const progress = useRef(new Animated.Value(0)).current;
const height = useRef(new Animated.Value(0)).current;
const progress = useAnimatedValue(0);
const height = useAnimatedValue(0);
// shared values
const progressSV = useSharedValue(0);
const heightSV = useSharedValue(0);
Expand Down
23 changes: 23 additions & 0 deletions src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useCallback, useRef } from 'react';
import { Animated } from 'react-native';
import { useEvent, useHandler, useSharedValue } from 'react-native-reanimated';

import type { EventWithName, Handlers, NativeEvent } from './types';
Expand Down Expand Up @@ -85,3 +86,25 @@ export function useSharedHandlers<T extends Record<string, Function>>() {

return { setHandlers, broadcast };
}

/**
* TS variant of `useAnimatedValue` hook which is added in RN 0.71
* A better alternative of storing animated values in refs, since
* it doesn't recreate a new `Animated.Value` object on every re-render
* and therefore consumes less memory. We can not use a variant from
* RN, since this library supports earlier versions of RN.
*
* @see https://github.com/facebook/react-native/commit/e22217fe8b9455e32695f88ca835e11442b0a937
*/
export function useAnimatedValue(
initialValue: number,
config?: Animated.AnimatedConfig
): Animated.Value {
const ref = useRef<Animated.Value | null>(null);

if (ref.current == null) {
ref.current = new Animated.Value(initialValue, config);
}

return ref.current;
}

0 comments on commit 6ea3499

Please sign in to comment.