react-native-shared-element
react-native-shared-element copied to clipboard
Basic example not working as a functional component
I tried to use the basic example with functional component and failed to to this. I saw there's already an issue discussing about it (https://github.com/IjzerenHein/react-native-shared-element/issues/9), but no answer was provide.
Using the navigation lib, everything is fine, but this librairy not. The main goal is to achieve the basic implementation so I can do more complex things.
Tried to use State, Refs but nothing is working, everytime I get errors like Error: Maximum update depth exceeded.
Repro : https://snack.expo.dev/@marc-hbb/sharedelement
EDIT : My final goal is to have a shared element transition on a view. With navigation, it seems that if I want to use it on a View (with an image inside), the image is laggy. On the other hand, on the "hero" example the shared element is a View. If there's a way to achieve this with react-navigation-shared-element please let me know ! :)
Hey! Thanks for opening the issue. The issue doesn't seem to contain a link to a repro (a snack.expo.dev link or link to a GitHub repo under your username).
Can you provide a minimal repro which demonstrates the issue? A repro will help us debug the issue faster. Please try to keep the repro as small as possible and make sure that we can run it without additional setup.
Hi, thanks for reporting and providing the Snack example 👍 I've had a closer look and the problem is indeed with using nodeFromRef from inside a functional component, which triggers the Maximum update depth exceeded error (as reported in #9).
I've modified the Snack to workaround this problem and saved it here: https://snack.expo.dev/@ijzerenhein/sharedelement
I replaced the ancestor <View> with a <SharedElement> node which is in fact nothing more than a component based View which translates ref into a node using nodeFromRef. This successfully mitigates the problem as you can see in the working example.
// before
<View style={styles.scene2} ref={...}>
<SharedElement onNode={setScene2Node}>
<Image style={styles.image2} source={require("./image.jpg")} />
</SharedElement>
</View>
// after
<SharedElement style={styles.scene2} onNode={setScene2Ancestor}>
<SharedElement onNode={setScene2Node}>
<Image style={styles.image2} source={require("./image.jpg")} />
</SharedElement>
</SharedElement>
SharedElement.tsx implementation
export class SharedElement extends React.Component<SharedElementProps> {
componentDidUpdate(prevProps: SharedElementProps) {
if (!prevProps.onNode && this.props.onNode && this._node) {
this.props.onNode(this._node);
}
}
private _node: SharedElementNode | null = null;
private onSetRef = (ref: any) => {
this._node = nodeFromRef(ref, true, this);
if (this.props.onNode) {
this.props.onNode(this._node);
}
};
render() {
const {
onNode, //eslint-disable-line @typescript-eslint/no-unused-vars
...otherProps
} = this.props;
return <View ref={this.onSetRef} collapsable={false} {...otherProps} />;
}
}
@MarcHbb let me know if you're able to have everything working as you want with the changes recommended by @IjzerenHein so we can close this issue :)