Skip to content

Reimplement Incubator.TouchableOpacity with reanimatedv2 #1380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 22, 2021

Conversation

ethanshar
Copy link
Collaborator

Description

Reimplement Incubator.TouchableOpacity with Reanimated v2
The component is currently exported as Incubator.TouchableOpacity2
eventually, we'll replace it with Incubator.TouchableOpacity (without a migration, since the API is the same)

Changelog

Reimplement Incubator.TouchableOpacity with Reanimated v2 as Incubator.TouchableOpacity2

@lidord-wix
Copy link
Contributor

Hey, few things:

  1. onLongPress acts on release instead of after a constant time.
  2. The onCancel doesn't work.
  3. The tabController doesn't work while using this touchableOpacity.

@ethanshar
Copy link
Collaborator Author

@lidord-wix
I fixed both 1. and 2.
And about 3. The current TabController is not using this TouchableOpacity so there shouldn't be any problem

@lidord-wix
Copy link
Contributor

lidord-wix commented Jul 14, 2021

@ethanshar
Will the TabController not use this TouchableOpacity in the future?

@ethanshar
Copy link
Collaborator Author

@ethanshar
Will the TabController not use this TouchableOpacity in the future?

I'm planning to use it in TabController2

Comment on lines 90 to 91
props.onPress?.(props);
}, [props]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the onPress need all the props as an argument?
This will update the callback for every prop change

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well technically you are right, we might consider an optimization for it.
But see first my big comment on the props feature we pass back during press callbacks.

.....That's the reason we pass all props, and that's why we all the props are in the deps arrays.

Anyway, I agree it's not optimal.
Maybe we can make an assumption that the "custom" prop the user passed is a static prop that won't change, then we can ignore all the props in the deps array. It means the user will get back the initial value they passed with a custom prop.
WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a reasonable assumption?
Maybe the user wants to know about props change, no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanna say that yes, it's reasonable. But technically if our assumption is wrong then it might introduce a bug.
Anyway, I have another solution.

Not so long ago, we added a dedicate prop called customValue to the original TouchableOpacity component.
See here -> https://github.com/wix/react-native-ui-lib/blob/master/src/components/touchableOpacity/index.tsx#L45

It's purpose was to be an explicit prop to pass on a custom value as I described in the previous comment.
Also the reason we had to declare an explicit type for it is due to typings.
When people use <TouchableOpacity someValue={...}/> it threw a TS error that someValue is not a valid prop.
So we have customValue and now they can just <TouchableOpacity customValue={...}/>

So back to our concern, see my recent code change.
I only condition the onPress callbacks on props.onPress and on props.customValue - which is the value that the user expect to pass on..

Let me know it all makes sense? (:

Comment on lines 94 to 95
props.onLongPress?.(props);
}, [props]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same answer (:

Comment on lines +36 to +40
onPress?: (props: any) => void;
/**
* Callback for when long pressing the touchable
*/
onLongPress?: (props: any) => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the type of props here is any?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because of a behavior/feature we added in uilib to our touchable components.
We pass back the props the user originally passed to the component.

Why?
It solve a common issue when rendering multiple repeating items (like in the case of lists) and other use-cases..

For instance, You can have the following renderItem method for a FlatList

renderItem = ({item, index}) => {
  return <TouchableOpacity onPress={() => doSomething(index)}  />
}

You see we have to pass an inline callback here (which is bad for performance) cause we need to pass on the specific index of the item, for each item.

With the feature we added, the user can do the following

doSomething = (touchableProps) => {
  const {index} = touchableProps;
  console.log('item index is:`, index)
}

renderItem = ({item, index}) => {
  return <TouchableOpacity onPress={doSomething} index={index}  />
}

Here we didn't have to pass an inline callback, we passed the callback by ref and another custom prop, the index.

That's why props in the onPress callback type is any, cause the user can basically pass/accept anything here.

Let me know if it's not clear, we can sync about It quickly..

@ethanshar ethanshar requested a review from lidord-wix July 18, 2021 07:05
@lidord-wix lidord-wix merged commit 9c91942 into master Jul 22, 2021
@ethanshar ethanshar deleted the infra/TouchalabOpacityV2 branch April 18, 2022 09:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants