-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
Invariant Violation: Touchable child must either be native or forward setNativeProps to a native component #1040
Comments
Custom component (in my case CommonThreadRow) has to set native props: setNativeProps: function (props: Object) {
this.refs[COMMON_THREAD_ROW].setNativeProps(props);
},
render: function () {
return (
<View ref={COMMON_THREAD_ROW}>
...
</View>
);
}, But it works only with TouchableHighlight. With TouchableOpacity it does not throw error but method _goToThreadDetail is not called after touch on wrapped view (CommonThreadRow component). |
cc: @vjeux |
The problem with those two components, is that they reach in the internals of the child via setNativeProps and POPAnimationMixin.startAnimation. In the meantime, you can wrap your children into a I'm working on a larger proposal that would address those two problems. The React way is to pass down updated values on every frame as prop and let the child component update on every frame. The issue is that if you don't implement shouldComponentUpdate in your child component (which is highly likely) then you're going to re-render large parts of your app and the animation or update will be really slow. So, in order to "fix" this, what we do is to take the underlying node and set the values directly. This works when you are passing native components such as View or Image, but if you are passing composite components it falls apart. This is a really unfortunate situation as the biggest strength of React is that you can build your app with those composite components. My idea is to pass down the current opacity as the style prop as usual, and let it any composite component in between manipulate it and thread it through an eventual native component. Then, the trick is to record on what native element and what style attribute it was eventually applied to. If you can store this information as metadata of the style value, then anytime you want to update it, you can just list all the affected elements and set their value directly. In order to make this work, you need the value to be opaque, meaning that all the composite components (which are implemented using arbitrary js) can only move it around but not be able to inspect the value. Thankfully for style, this isn't an issue in practice as all the objects returned from StyleSheet.create are already opaque. You'll likely hear more from this crazy idea in the next few weeks :) |
Thank you for very detailed answer. |
Previously, there was no way how to simply pass arguments from <Lightbox> to the renderContent(). The only possibility was to create a new component and utilize activeProps what works fine for simpler cases. But this component has to be either native or it have to forward setNativeProps. Such forwarding may be a little more complex as shown at facebook/react-native#1040 where change of application logic was the solution. Such solution does not make sense with <Lightbox>.
adding to "michalraska" answer solved my problem basically just changed the COMMON_THREAD_ROW as a string instead of object: setNativeProps(props: Object) { |
@Aadesh05 string refs are bad-practice, so @michalraska was doing it better: https://facebook.github.io/react/docs/refs-and-the-dom.html
|
@vjeux So, umm, where is this crazy idea...? I'm still getting this same error after 2 years... |
I get this error with the following code: <TouchableHighlight onPress={() => { appSwitchToLink(link.href) }}>
<View>
<PAText style={styles.link}>
{link.title}
</PAText>
</View>
</TouchableHighlight>
|
This resolved the error that I was getting:
Wrapping the internal element within a view tag was magic |
WTF? Why is this necessary? And why is it not documented? |
Previously, there was no way how to simply pass arguments from <Lightbox> to the renderContent(). The only possibility was to create a new component and utilize activeProps what works fine for simpler cases. But this component has to be either native or it have to forward setNativeProps. Such forwarding may be a little more complex as shown at facebook/react-native#1040 where change of application logic was the solution. Such solution does not make sense with <Lightbox>.
Hi,
when I'm trying to wrap my custom component by TouchableOpacity
so application falls with error:
Invariant Violation: Touchable child must either be native or forward setNativeProps to a native component
How to solve this?
Thank you.
The text was updated successfully, but these errors were encountered: