Accepting Payments in a React Native App (Part 4)
Building the Payment Client Using React Native and React
Additionally, this project is available as the react-native-webview-braintree npm package for you to use in your own projects.
Those other articles can be found here:
1. Project Introduction. This section may not sound like much, but it’s a good explanation on how everything will fit together.
2. Application Server using Amazon Web Services. This portion explains how to interact with Braintree’s server in a secure manner.
4. React Component Based Version is about putting React inside a React Native application.
<div> element that serves as the “target” to place the compiled React JSX into. This creates a bundle.js file which is compiled into an index.html file which is then imported by the React
<WebView/> component for rendering.
So, one may ask, why go through the trouble of even using React inside a React Native webview.
For one, I did it because I thought that taking advantage of the reactive nature of React in both the React and React Native portions of my project would lead to cleaner, understandable, and more maintainable code; some of the primary reasons for using React in the first place. Additionally, it meant that I could follow the same pattern for creating both components. Since this version of the project uses react-native-webview-messaging just like the previous version, I could set up listeners and fire messages same way both the React and React Native sides.
This change represents the most significant differences between this and previous versions of this article.
Since I’m assuming that you’ve read my previous article in this series, I will be focusing on the React code and packaging it for use by react-native-webview-messaging.
Once again, I relied on webpack to convert the JSX into HTML that my
<WebView> could use as it’s source prop.
Again, it’s very similar to my previous version. The most import part is line 29 which tells babel to transpile any JSX it finds into JS. Line 6 tells babel to begin working in the braintreeReact.js file which contains the React code, and line 41 tells babel which html file to combine with braintreeReact.js to create the final index.js that will be imported by the react-native-messaging-webview.
Next, I’ll walk through the code in
braintreeReact.js. Don’t worry if it seems like a lot of code. For one thing, I like white-space. Additionally, I’ll go though the important parts line by line below.
On lines 3 and 4 I manually import a downloaded version of React. I encountered errors attempting to use the version of React in my node modules directory. I attributed this to version conflicts due to using Expo, which has it’s own specific React dependencies.
Line 8 imports glamorous which I used for styling in lines 12 to 36.
PrintData function on line 40 is used for debugging. Debugging a
<WebView/> can be difficult since you can’t rely on console logs and breakpoints. To get around this, the
PrintData function prints passed objects and strings to a
<div> element in the
Line 52 is where the actual BraintreeHTML component starts. It initially has one state variable,
currentPaymentStatus which is used to conditionally render feedback to the user throughout the payment process.
componentDidMount function provides an opportunity to register listeners for interaction with the parent component.
createCreditCardUI function does exactly the same thing as before. It places the Braintree UI inside of a
<div> element on the index.html. It then saves the Braintree
instance object in the component’s state for later use.
Next, the handler
handleSubmitPurchaseButtonClicked function does exactly what it’s name suggests. It is fired once the user clicks the button that submits purchase information, at which point it sets the
currentPayementStatus state variable to “PAYMENT_PENDING” and emits a “RETRIEVE_NONCE_PENDING” message to the parent so that it can display an
<ActivityIndicator/> component. It then requests a nonce using the Braintree API’s
requestPaymentMethod of and submits either a message indicating success or failure to the parent component.
Several things are happening inside the render function. First, the components created with glamorous are used to format individual elements. More importantly,
renderIf from the render-if library is used to conditionally render either the payment UI, a message thanking the user for their purchase, or a message informing the user that their was a problem with their payment. The value of the component state variable
currentPaymentStatus determines which of the three are rendered.
This post shows that it is possible to use React to create the content of a React Native
<WebView/> . It also demonstrated a method to communicate between the
<WebView/> and the HTML created by the React. Additionally, it demonstrated a technique to show useful debugging information from the HTML which itself has no access to the console or the debugger.