📜 ⬆️ ⬇️

About React Native



A few tips on what you need to know to write (or not to write) applications under React Native.

Immediately, I’ll make a reservation that I have never written an application for iOS, but I have already participated in at least 4 projects with React.js, I understand a little about objective-c and am familiar with the Android development process.
')
The application is quite simple (todo list), but I think this is a good start.

Task: write task manager with monetization. There are interface sketches for invisionapp, the rest is a matter of technology.

Data flow


The most important thing in react applications is to correctly build the data-flow and interaction between the various components from the very beginning. Then there is a chance that the components will only render the data, and not turn into a sheet of asynchronous calls and a bunch of logic that “can later be taken out” somewhere else. The Redux library comes to the rescue. I will not describe in detail how it works (information can be found here and here ).

The application has one store with a global state. It is assembled from several reducers processing individual collections. For convenience, I also recommend connecting redux-thunk and some devtool to track the states of the store. Unfortunately, for native I did not find anything like it, but this is not a problem, because trace status is written in 10 lines.

Middleware code
var i = 0 const devtools = store => next => action => { const result = next(action) if (console.group) { console.group(`#${i++}`, action.type, action) _(store.getState()).map((val, key) => { console.log(key, val) }) console.groupEnd() } return result } 


Redux-thunk is needed for combining several asynchronous actions, as well as for actions that require getting the current state. Example: For a task, you need to create a result that is placed in another collection, make a payment and mark the task as archived. There are 3 collections and 3 different actions (all asynchronous).

The global state allows us to take a snapshot of the store at any time, download it on another device and see the same thing that we saw on the first one. This simplifies the process of reproducing bugs during crash reports (try to do the same on objective-c). The idea is not new: the clojure-script wrapper for react uses the exact same approach. There are several presentations that talk about the pros and cons of a solution. Speaking of crash reports, I use Crashlytics (now Fabric.io) .

In addition, the global state makes it easier to work with navigation (I thought so). In fact, I had to fence the wrapper for the native navigator, do an index of operations, and duplicate the redux actions with method calls in the componentWillReceiveProps.

Component code
  componentWillReceiveProps(props) { const routes = props.routes if (this.props.routes.opIndex != routes.opIndex) { switch(routes.lastAction) { case 'push': this.refs.navigator.push(routes.currentRoute) break case 'pop': this.refs.navigator.pop() break case 'replace': this.refs.navigator.replace(routes.currentRoute) break case 'replacePreviousAndPop': this.refs.navigator.replacePrevious(routes.currentRoute) InteractionManager.runAfterInteractions(() => { this.refs.navigator.pop() }) break } } } 


Use promises (or await / async ES syntax). If you return them from redux actions, you can easily make, for example, a loader.

Speed ​​and layout


Layout is one of the most enjoyable processes in React Native. In Android, xml is also used for layouts and it is convenient if you sit and figure out what it serves for. However, in the reactor, you already know how it works ... if you need to roll out hello, world :) In fact, the unpredictable behavior of the components is obtained. "Position: absolute" does not work like in the browser, the flux-box also works differently, the images do not automatically set the size of the width and height of the picture. It turns out that you, as it were, know what to write, the code is being executed, but this does not look the way we would like. It saves only adequate documentation and live reload, but it is still more convenient than the layout for android.

Each time adding a new View to the hierarchy, a thought occurred to me: “will it be rendered for a long time?” Long. Large components need to make a loading screen, but facebook warns about it. If you are going to hang some kind of logic to create a component (for example, loading data from the storage at the start of the application), pay attention to the InteractionManager. It will allow you to first render everything that has accumulated and only then execute your actions.

With regard to the performance of the application as a whole: it turns out anyway a little slower than native applications. However, for most users, this will not be noticeable. If you would like to draw your sidebar (like for example in airbnb), then the reaction is not the most suitable solution, you need to write the native component. Although there are implementations, but, unfortunately, not yet in the form of a library.
Another example: Navigator and NavigatorIOS. The first is written in js, the second as a native component. NavigatorIOS works faster if you sit for a long time and look at the transitions between scenes :) Again, most users will not even notice the difference. The whole problem lies in the fact that data management and element position rendering occur in one stream, hence the lag. Fortunately, I did not have to write native components, I managed to optimize everything by calling InteractionManager and gradually loading the components.

Handling events from the user also requires attention. If you take TextInput and make the value / onChage in the state of the current component, everything works quickly, but if you start passing props to the parent component and do the processing, 100% will need debounce. By the way, it works quickly in the browser. Another note about TextInput: when iOS substitutes a word AutoCorrect, onChageText is not called. I did not solve this problem and, frankly, did not try. You can simply disable autoCorrect by false.

Third Party Libraries


If you need a sidebar, menubar, some tricky image loader with progress or calendar, then there are ready-made solutions. There are, but they are not as many as we would like. It turns out the choice is not very large. Many components endure management techniques that do not fit well with the rendering logic from the global state. I would like more value / onChange :)

Anyway, there are libraries and I did not have to write a lot of bicycles. In addition, the repositories are constantly updated, so do not forget to do npm update periodically in your project before fixing the bug in the libraries.

Debag and testing


With this, the reactor is all fine. You can run the application on two devices at once (I launched on the iPhone and iPad for tests) and when you change, for example, layouts, the changes are simultaneously displayed on two devices at once. Very comfortably. There are some problems when debugging on a device using google chrome. Sometimes chrome can fly, sometimes the application does not have time to connect to the computer. The last time he just began to pour in the console warning'i due to the fact that time is running out. This can be experienced, after all, after all, a mobile application.

For automatic testing, I used jest (you can use any other test runner). Tests covered only actions and reducers. Components are not covered, because there are many, and time is limited. Information on testing react native components is small, but if you go deep, you can lock it up so that you can test the layout.

Conclusion


For me, as a web developer, the appearance of react native greatly facilitates the development of mobile applications, now I can transfer my knowledge to another area, but I must at least understand the syntax objective-c to write under iOS. React Native, and React by itself allows you to respond to changing customer requirements without straining. When you get a new task, you probably already know how to implement it.

PS In total, it took me a little more than a month to write an application from scratch with zero knowledge of development under ios.

Screenshot


Mastrid before writing applications: facebook.imtqy.com/react-native/docs/performance.html

Source: https://habr.com/ru/post/275145/


All Articles