Skip to content
This repository has been archived by the owner on Nov 27, 2022. It is now read-only.

Provide a ForwardRef for position value #1187

Open
cr0ybot opened this issue May 28, 2021 · 4 comments
Open

Provide a ForwardRef for position value #1187

cr0ybot opened this issue May 28, 2021 · 4 comments

Comments

@cr0ybot
Copy link

cr0ybot commented May 28, 2021

Current behaviour

After the v2 update, the passing of a position ref no longer works. This would be useful for animating other components according to the pager view position outside of the TabView hierarchy.

Expected behaviour

I expected a position ref passed as the position prop to TabView would give me the ability to use the TabView position in other components outside of the TabView hierarchy, as proposed in issue #781 and merged in PR #782.

Code sample

const AnimatedComponent = ({ position }) => {
  const interpolatedPosition = position.interpolate({
    inputRange: [...],
    outputRange: [...],
  });

  return (
    <Animated.View style={{ someStyleProp: interpolatedPosition }}>
      {...}
    </Animated.View>
  );
}

const ScreenComponent = () => {
  const position = useRef(new Animated.Value(0));

  return (
    <TabView position={position} navigationState={{...}} />
    <AnimatedComponent position={position.current} />
  );
}

Screenshots (if applicable)

What have you tried

I have clumsily hacked around the issue by pulling the position value from the renderTabBar function, as the position prop is passed there. This works but is less than ideal, especially if I have no need to replace the default TabBar.

Here is my workaround (copied from #781 (comment)):

const AnimatedComponent = ({ position }) => {
  const interpolatedPosition = position.interpolate({
    // NOTE: inputRange should match the number and indices of the routes from navigationState
    inputRange: [...],
    outputRange: [...],
  });

  return (
    <Animated.View style={{ someStyleProp: interpolatedPosition }}>
      {...}
    </Animated.View>
  );
}

const ScreenComponent = () => {
  const position = useRef(new Animated.Value(0));

  const renderTabBar = (props) => {
    position.current = props.position;
    return (
      <TabBar {...props} />
    );
  };

  return (
    <TabView renderTabBar={renderTabBar} navigationState={{...}} />
    <AnimatedComponent position={position.current} />
  );
}

Your Environment

software version
ios & android 14.5 & 28
expo 40.0.0
react-native 0.63.2
react-native-tab-view 3.0.1
react-native-pager-view 5.1.10
node 14.17.0
npm 7.13.0
@cr0ybot cr0ybot added the bug label May 28, 2021
@github-actions
Copy link

Couldn't find version numbers for the following packages in the issue:

  • react-native

Can you update the issue to include version numbers for those packages? The version numbers must match the format 1.2.3.

The versions mentioned in the issue for the following packages differ from the latest versions on npm:

  • expo (found: 40.0.0, latest: 41.0.1)

Can you verify that the issue still exists after upgrading to the latest versions of these packages?

@satya164
Copy link
Owner

I don't think a ref would work since it means you can't use it for the first render, and you won't get updated value until next render since changing a ref doesn't trigger re-render. Open to other ideas tho.

@cr0ybot
Copy link
Author

cr0ybot commented Aug 11, 2021

Maybe asking for a forward ref specifically was the wrong way to go about this, I just assumed since passing a position ref was a feature previously that something similar would still work. The goal is to be able to pass the position value to other components, however that can be accomplished. Maybe an optional onPositionChange function prop that can be passed to TabView and is called any time the position value changes? Then the user of this component can handle that change however they see fit.

@satya164
Copy link
Owner

Maybe an optional onPositionChange function prop that can be passed to TabView and is called any time the position value changes? Then the user of this component can handle that change however they see fit.

This is also problematic since it means whatever animation user is doing will be completely JS-based and unable to use native driver.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants