Imagine, you are working on a social network application. You implement a button to create a new post. Your code would probably be like the following:
++pre>++code>...
const createPost = () => {
displayPostCreationModal();
}
...
<NewPostButton onPress={createPost} />
...
++/code>++/pre>
Then you decide to implement a post sharing. The share button can use the same function, we will just slightly modify it:
++pre>++code><ShareButton onPress={() => createPost(sharedPost)} />
++/code>++/pre>++pre>++code>const createPost = (sharedPost?) => {
if (sharedPost) {
displayPostCreationModal(sharedPost.message);
}
else {
displayPostCreationModal();
}
}
++/code>++/pre>
The implemented functionality works fine: when you press the share button, you see a modal with a pre-filled message.
Everything looks fine until the moment you press again the button creating a new post from scratch...
++table cellpadding="4" style="width: 100%; border-collapse: collapse; table-layout: fixed; border: 1px hidden #FFFFFF; border-width: 0px; border-style: none;">++tbody>++tr>++td style="width: 19.7863%;">
++/td>++td style="width: 86.2356%;"> undefined is not an object (evaluating 'sharedPost.message.length')++/td>++/tr>++/tbody>++/table>
The appeared error is confusing because the only place you try to access sharedPost.message is the if scope of the createPost function. While when we create a new post... we do not provide any parameter ?
Indeed, if you place breakpoints at the beginning of each scope and press the NewPostButton, you will stop in the if scope and see your sharedPost be an object with not really expected content: {"_dispatchInstances": {"_debugHookTypes": null, "_debugIsCurrentlyTiming": false, ... (it is long, I will not fully present the object here, but there is nothing about shared post or its message)
I will avoid beating around the bush and come straight to the point.
The problem comes from the "secret" onPress parameter.
Here is the ReactNative onPress type: ((event: GestureResponderEvent) => void) | undefined.
Back to the example: we were actually trying to execute createPost(event). The event parameter was thereby treated as a sharedPost , which provoked the error crashing our application.
++code>PressEvent++/code> object is returned in the callback as a result of user press interaction, here is the documentation.
The ++code>onPress++/code> property of many React Native core components uses the event argument in form of ++code>PressEvent++/code>: ++code>Button++/code>, ++code>TouchableOpacity, TouchableWithoutFeedback,++/code> ++code>Pressable++/code>, etc. The situation is the same with ++code>onPressIn ++/code>and ++code>onPressOut++/code> props that some of listed components have.
The PressEvent ++code>++/code> is mainly used inside the React Native code for managing the behavior of different touchables. If you have a real-live example of its utilization, do not hesitate to share it ?
To resolve the problem, we can simply modify onPress of the button creating a new post: precise that createPost function should be called without parameters like below:
++pre>++code><NewPostButton onPress={() => createPost()} />++/code>++code>++/code>++/pre>
As any bug, even more than know how to fix it, we would rather not have it at all ?
So, here are some steps that could prevent its introduction.