11import * as React from 'react'
2- import { forwardRef , useRef , Ref } from 'react'
2+ import { forwardRef , useRef , Ref , useCallback } from 'react'
33import { useLayoutEffect } from 'react-layout-effect'
44import { is , each , useForceUpdate , ElementType , FluidConfig } from 'shared'
55
@@ -8,14 +8,26 @@ import { HostConfig } from './createHost'
88
99export type AnimatableComponent = string | Exclude < ElementType , string >
1010
11- export const withAnimated = ( Component : any , host : HostConfig ) =>
12- forwardRef ( ( rawProps : any , ref : Ref < any > ) => {
11+ export const withAnimated = ( Component : any , host : HostConfig ) => {
12+ const hasInstance : boolean =
13+ // Function components must use "forwardRef" to avoid being
14+ // re-rendered on every animation frame.
15+ ! is . fun ( Component ) ||
16+ ( Component . prototype && Component . prototype . isReactComponent )
17+
18+ return forwardRef ( ( givenProps : any , givenRef : Ref < any > ) => {
1319 const instanceRef = useRef < any > ( null )
14- const hasInstance : boolean =
15- // Function components must use "forwardRef" to avoid being
16- // re-rendered on every animation frame.
17- ! is . fun ( Component ) ||
18- ( Component . prototype && Component . prototype . isReactComponent )
20+
21+ // The `hasInstance` value is constant, so we can safely avoid
22+ // the `useCallback` invocation when `hasInstance` is false.
23+ const ref =
24+ hasInstance &&
25+ useCallback (
26+ ( value : any ) => {
27+ instanceRef . current = updateRef ( givenRef , value )
28+ } ,
29+ [ givenRef ]
30+ )
1931
2032 const forceUpdate = useForceUpdate ( )
2133 const props = new AnimatedProps ( ( ) => {
@@ -35,25 +47,17 @@ export const withAnimated = (Component: any, host: HostConfig) =>
3547 } )
3648
3749 const dependencies = new Set < FluidConfig > ( )
38- props . setValue ( rawProps , { dependencies, host } )
50+ props . setValue ( givenProps , { dependencies, host } )
3951
4052 useLayoutEffect ( ( ) => {
4153 each ( dependencies , dep => dep . addChild ( props ) )
4254 return ( ) => each ( dependencies , dep => dep . removeChild ( props ) )
4355 } )
4456
45- return (
46- < Component
47- { ...host . getComponentProps ( props . getValue ( ) ! ) }
48- ref = {
49- hasInstance &&
50- ( ( value : any ) => {
51- instanceRef . current = updateRef ( ref , value )
52- } )
53- }
54- />
55- )
57+ const usedProps = host . getComponentProps ( props . getValue ( ) ! )
58+ return < Component { ...usedProps } ref = { ref } />
5659 } )
60+ }
5761
5862function updateRef < T > ( ref : Ref < T > , value : T ) {
5963 if ( ref ) {
0 commit comments