Richard Evans

Developing in React Native with Reactotron

Ancient City Ruby 2019

00:00:15.860 Well, I was going to start off by telling you who I am, but now you know. Basically, what I want to talk to you about is using Reactotron, specifically with React Native. It can also be used with React DOM or any other libraries for React on the web, but the benefits really shine when it comes to React Native.
00:00:21.000 So, we're going to focus on React Native for this presentation, but I want to start off with a few questions for you. How many of you have written something using Reactotron?
00:00:25.080 Okay, quite a few of you. Perfect! How about React Native? More than I was expecting. That's great! And how many of you have experience with state management libraries? Who has strong opinions about them?
00:00:36.960 Finally, while you were developing, how many of you wished you had more insights into what was going on in your app? I hope that I'm going to show you a little bit about how to gain more insights into your application, especially since the formatting is a bit off today.
00:00:50.880 So, what is Reactotron? Reactotron is a desktop app that assists in inspecting and debugging your React DOM and React Native projects. I apologize as I didn't set this up at the right resolution, so bear with me while we get through this.
00:01:02.370 Reactotron is made up of a few different libraries and an Electron app. The app itself is an Electron desktop application, which we briefly saw yesterday, but we'll examine it further today. It comprises two client libraries for React and React Native; these connect to Reactotron and send information over WebSockets.
00:01:14.860 Additionally, we have the Reactotron Core client, which is the actual library that hooks up to the WebSocket. This can be used to create libraries for other frameworks like Vue or any others you might wish to use. We'll also touch on React-Redux and Redux-Saga in this context.
00:01:24.540 These components work together to allow us to inspect our app and see what's going on within it. To illustrate this, we're going to build an app, but I’m not brave enough to write it live, so we have some requirements laid out. Essentially, we're going to facilitate communication between two users, which may not be as impressive live as what we've just seen.
00:01:41.280 Our UI should be familiar, so we’ll be going for a messaging interface to keep it simple. We're going to create two base components, assuming the app could evolve into something more robust, and we'll take a 'Chatroulette' approach where users do not have to identify themselves.
00:02:01.440 Moving on, I won’t code this live; instead, I’ll walk you through the existing code. We'll start with the imports. Most of them are straightforward: React, React Native, and various libraries. Because we're using Redux in this example, I'll add Redux as well.
00:02:18.150 I know some may have opinions that Redux is not the best, but everything I'll show you here will also work with MobX and other state management libraries.
00:02:28.170 Next, we have the Reactotron imports. From the previous slides, you can see I'm using the Reactotron package and the Redux plugins for integrating it with our React setup.
00:02:48.640 When setting up Reactotron, you can configure a range of options. For example, you can give your app a name if you’re working with multiple applications, allowing for easier identification within Reactotron.
00:03:02.740 You can specify a host, which is where your Reactotron app is running. If it's on a different machine, you can provide the IP address. For simplicity, we can skip this and default to localhost, which is great for working in the simulator. We'll also set up an Async Storage handler in Reactotron.
00:03:24.570 This is necessary because React Native's lean core efforts have taken away certain storage solutions, making it essential for Reactotron to know where Async Storage is being utilized. We’ll then wire up Redux and Redux Saga with Reactotron for complete integration.
00:03:37.410 As we connect, we will begin to receive data instantly. One of the interesting capabilities of Reactotron is that it provides a detailed view of the client that connected, revealing aspects such as the platform and various other data.
00:03:45.590 You can also delve into and subscribe to different pieces of the application state, thereby tracking the messages we receive and how the actions flow within our application. Additionally, we have custom commands available, which let us execute some of the code we’ve written.
00:04:07.870 With these commands, we can execute, for example, a hello command that logs specific messages into our store. This functionality can be quite useful, especially when simulating behaviors before the user interface is fully developed.
00:04:21.730 Next up is a walkthrough of the application that we can actually work with. This app, although simple, serves as a working example where simplicity is key to aiding our demonstration. In this instance, we will only utilize basic API requests instead of jumping straight into GraphQL.
00:04:52.340 Throughout the demo, I'll return every message that was previously sent whenever a message is posted. While I do not recommend this approach in production, it's acceptable here for demonstration purposes.
00:05:01.250 Setting up Redux can be quite the task; as many of you know, boilerplate can accumulate quickly. The structure includes three sagas, one reducer, and a handful of action types.
00:05:10.680 We start off by defining our action constants. Using constants allows us to avoid issues in the reducers due to duplicate action types. Following this, we set up our sagas.
00:05:31.410 One root saga will help us manage our two other sagas, which handle the messages. We will call the API and store the results back into Redux to update our application state.
00:05:44.540 For sending messages specifically, the saga will allow us to select the current message from the Redux store. While some argue against storing form state in Redux, for our purposes, this is the approach we'll take.
00:05:59.130 This setup allows us to effectively send messages while also managing two different actions. Now, we should move on to wiring everything up and connecting our actions.
00:06:14.490 Next, we look at the reducer, which is simply responsible for holding the state of our app and responding to action types that we defined earlier, populating and updating the Redux store.
00:06:19.780 This section, which I've highlighted, shows our initial state as well as the action types.
00:06:28.230 The final setup stage involves creating the Redux store and wiring it to Reactotron. This step is crucial as it allows us to leverage Reactotron for debugging functionalities.
00:06:44.240 When in development mode, we will create a saga monitor, which provides a set of functions to track and monitor the status of our sagas. This information is passed into the create saga middleware to observe actions, states, and other vital information.
00:06:56.020 After creating the middleware and linking everything together, we will set the store to Reactotron. Admittedly, this connection process is a necessary but unfortunate requirement.
00:07:12.950 Moving on, we’ll create custom commands to run arbitrary functions. These commands will let us manipulate the state and perform various actions even before our user interface is in place.
00:07:29.300 Let's shift gears and look at the app that we’ve got working. Currently, I will display a minimalistic interface with a blank screen. As I reload the app, we’ll see live updates on the right side, where Reactotron captures all interactions.
00:07:48.330 When we connect, data starts streaming instantly, showcasing information about the client connected, which includes platform details and various other relevant data. This provides significant insight into the app's current states.
00:08:16.770 You may also notice a timeline of actions that captures everything happening in the application. You have the ability to see actions with their payloads, allowing for an in-depth debug experience.
00:08:35.720 We can choose to edit any previous action, modify its parameters, and dispatch it anew to observe its effects. In addition to this, Reactotron tracks API requests initiated from the React Native side.
00:08:54.130 For every API request, you will be able to see all relevant information such as request headers, response headers, and so on. There are features available to copy request/response details as a markdown format, making it easy to document or share.
00:09:11.750 Additionally, Reactotron provides several React Native specific tools. One of these is the image overlay functionality, which allows you to drag and drop a design file onto your simulator for visual reference.
00:09:36.930 This feature helps in achieving pixel-perfect designs as required by designers and enhances the collaboration between development and design teams.
00:09:53.650 Next, we will showcase Storybook. In order to leverage Storybook, I will first present two components that will structure the entirety of our application.
00:10:16.350 The first component will be the chat input field, designed to be entirely stateless, meaning it doesn’t interact with the Redux store and relies solely on props for data.
00:10:31.650 The second component will be the chat bubble, which will display incoming messages. This structure emphasizes the flow of data and clear separation of concerns in component design.
00:10:47.400 Now, let’s move to the final segment as I showcase how this comes together in the main app. This app is relatively simple and uses React hooks provided by Redux to facilitate easy state management and action dispatching.
00:11:09.440 We’re focusing on how to set user IDs randomly for our demo since anonymity is key in our app concept. This random generation method will help simulate a realistic usage scenario.
00:11:24.560 To maintain the flow of messages, we will fetch updates every 5 seconds to avoid flooding Reactotron with too many updates. The simplicity of this app allows us to focus on how these components work together.
00:11:41.700 Let’s check out how the user interface looks. Here we have the final output, including all messages we have sent and received during testing. You can observe the dynamic behavior as messages update seamlessly.
00:11:57.930 As interactions happen, requests are monitored in real-time within Reactotron, yielding insights into both the UI component and the Redux state.
00:12:11.590 You can initiate searches, filter actions based on type, toggle between reversing the action order, and even download the action logs as markdown files for sharing purposes.
00:12:34.410 Furthermore, Reactotron offers a unique snapshots feature that allows you to freeze the application state at any given moment, making it easier to debug specific conditions or behaviors.
00:12:53.440 You can easily name snapshots for effective debugging, share states, and use them for comparison when testing various scenarios during development.
00:13:17.180 As we approach the conclusion of our presentation, I'd like to emphasize that the tools we've discussed and shown today provide powerful capabilities to enhance your React Native development process.