Ilja
Ilja

Reputation: 46479

Pass functional component to Animated.createAnimatedComponent

If you try to pass functional (non react class) component to Animated.createAnimatedComponent it throws an error that says

Stateless functional components are invalid as children of createAnimatedComponent

Coming from an app that uses react hooks, basically all of my component are functional.

Is there a way / helper that can allow to pass these to createAnimatedComponent without wrapping them in Animated.View or even just View?

Here is an example of component that I want to make animatable

function MyComponent({ someProp }) {
  const [counter, setCounter] = useState(0);

  return (
    <View>
      <Text>{counter}</Text>
    </View>
  );

}

Upvotes: 6

Views: 4595

Answers (3)

Dalton
Dalton

Reputation: 137

Adding to @MJ Studio's answer to add prop type assertion:

export function withAnimated<T extends object>(
  WrappedComponent: ComponentType<T>
): ComponentClass<AnimatedProps<T>, any> {
  const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component';

  class WithAnimated extends Component<T> {
    static displayName = `WithAnimated(${displayName})`;

    render(): ReactNode {
      return <WrappedComponent {...this.props} />;
    }
  }

  return Animated.createAnimatedComponent<T>(WithAnimated);
}

Usage:

const MyAnimatedComp = withAnimated(MyCompWithCustomProps);
// MyAnimatedComp is typed as React.ComponentClass<AnimatedProps<MyCompCustomProps>, any>

Upvotes: 0

MJ Studio
MJ Studio

Reputation: 4611

How about this HOC

export function withAnimated(
  WrappedComponent: React.ComponentType<any>,
): ComponentType {
  const displayName =
    WrappedComponent.displayName || WrappedComponent.name || 'Component';

  class WithAnimated extends React.Component {
    static displayName = `WithAnimated(${displayName})`;

    render(): React.ReactNode {
      return <WrappedComponent {...this.props} />;
    }
  }

  return Animated.createAnimatedComponent(WithAnimated);
}

Usage

export const AnimatedGradientButton = withAnimated(GradientButton);

Upvotes: 9

gian117
gian117

Reputation: 246

As far as I can tell, your options are:

1) Change to class component

2) Wrap your component in a View which you then animate

3) Use react-native-animatable (or a solution similar as this offers): check here for a combination of the library and refs

4) Maybe a solution similar to this one would suit you better. Combination of useRef and useEffect.

Upvotes: 5

Related Questions