React Native

 3r33581. 3r3-31. You woke up. The sun is shining, birds are chirping. In the world, no one is fighting with anyone, no one is hungry, and the same code can be used in web projects and in native applications. How good it would be! Unfortunately, only a universal code can be seen on the horizon, but the path to it, even today, is still full of surprises. 3r33565.  3r33581. 3r33565.  3r33581. React Native 3r? 3569. 3r33565.  3r33581. 3r33565.  3r33581. The material, which we are publishing today, is a small but fairly detailed guide to developing universal applications using React Native. 3r33565.  3r33581.
3r? 3569. 3r33565.  3r33581. 3r3-3549. 3r33550. Why is this all about? 3r? 3551. 3r???. 3r33565.  3r33581. The abbreviation "PWA" (3r-325. Progressive Web Apps 3r-3669., Progressive web applications) is widely heard today, this three-letter acronym seems like a whale in a sea of ​​technical terms. But this popular technology is still not without 3r-327. disadvantages 3r36969. . There are many technological difficulties associated with such applications, there are situations in which the developer is forced to simultaneously create native and web applications.
Here is 3r3-3569. A good article that compares PWA and native applications. 3r33565.  3r33581. 3r33565.  3r33581. Maybe business should focus only on native applications? No, not worth it. This is a big mistake. As a result, the development of a single universal application becomes a logical step. This reduces the time spent on development, reduces the cost of creating and supporting projects. It was these characteristics of universal applications that prompted me to one small experiment. 3r33565.  3r33581. 3r33565.  3r33581. This is a universal example application from the field of e-commerce for ordering food. After the experiment, I created a template for future projects and for further research. 3r33565.  3r33581. 3r33565.  3r33581. 3r???.
Good morning! Standard web container at your service! 3r? 3577. 3r33515. 3r3494. 3r33565.  3r33581. A native - so: 3r33565.  3r33581. 3r33565.  3r33581.
3r???.
Hello! I am a simple container in React Native
3r33515. 3r3494. 3r33565.  3r33581. Some clever people have found a way out of this situation. The output became specialized libraries of elements. One of my favorites is the wonderful
library. React Native Web
. It not only takes care of the basic primitives of the application, allowing you to use React Native components on the web (not all components!), But also gives access to various React Native APIs. Among them - 3r33514. Geolocation , 3r???. Platform 3r33515. , 3r???. Animated , 3r???. AsyncStorage and many others. Take a look at the wonderful examples that can be found in manual. to this library. 3r33565.  3r33581. 3r33565.  3r33581. 3r3-3549. 3r33550. Template 3r33551. 3r???. 3r33565.  3r33581. We figured out the primitives. But we still need to link environments for web development and for native development. In my project used create-react-app (for web application) and 3r3r116. 3r36969 initialization script. React Native (for a native application, without Expo). First, I created one project with the following command: 3r33514. create-react-app rnw_web . Then he created a second project: 3r3-3144. react-native init raw_native . Then, following the example of Victor Frankenstein, I took the files 3r???. package.json of these two projects and combined them. After that, in the folder of the new project, I fed a new file 3r33514. yarn 3r33515. . This is what 3r??? is about. package - File in question: 3r3-3565.  3r33581. 3r33565.  3r33581.
3r???. {3r3-3581. "name": "rnw_boilerplate",
"version": "???", 3r33535. "private": true,
"dependencies": {
"react": "^ ???", 3r-33581. "react-art": "^ ???", 3r33581. "react-dom": "^ ???", 3r33581. "react-native": "???",
"react-native-web": "^ ???", 3r3353581. "react-navigation": "^ ???",
"react-router-dom": "^ ???", 3r33535. "react-router-modal": "^ ???" 3r3353581.}, 3r33581. "devDependencies": {3r33571. "babel-jest": "^ ???",
"babel-preset-react-native": "^ 5",
"jest": "^ ???", 3r33581. "react-scripts": "???", 3r33535. "react-test-renderer": "^ ???" 3r353581.}, 3r33581. "scripts": {
"start": "node node_modules /react-native /local-cli /cli.js start",
"test": "jest",
"start-ios": "react-native run-ios",
"start-web": "react-scripts start",
"build": "react-scripts build",
"test-web": "react-scripts test --env = jsdom",
"eject-web": "react-scripts eject"
}
} 3r33515. 3r3494. 3r33565.  3r33581. Please note that this version of the file has no navigation options. Next, you need to copy all the source code files from the folders of the web application and the native application to the folder of the new unified project. 3r33565.  3r33581. 3r33565.  3r33581. 3r3172. 3r33565.  3r33581. 3r33175. 3r3176. Folders that need to be copied to the new project 3r33551. 3r3178. 3r33565.  3r33581. 3r33565.  3r33581. Now, in the folder. src 3r33515. which is in the directory of the new project, create two files: 3r33514. App.js 3–3–3515. and 3r?314. App.native.js . Thanks to 3r3r9189. webpack 3r36969. we can use file name extensions to tell the bundler where to use which files. Divide App 3r3353515. The files are vital since we are going to use different approaches to navigate through the applications. 3r33565.  3r33581. 3r33565.  3r33581. Here is the file 3r???. App.js 3–3–3515. intended for the web. For navigation, use 3r???. react-router . 3r33565.  3r33581. 3r33565.  3r33581.
  3r???. //App.js - WEB
import React, {Component} from "react"; 3r33581. import {View} from "react-native"; 3r33581. import WebRoutesGenerator from "./NativeWebRouteWrapper/index"; 3r33581. import {ModalContainer} from "react-router-modal"; 3r33581. import HomeScreen from "./HomeScreen"; 3r33581. import TopNav from "./TopNav"; 3r33581. import SecondScreen from "./SecondScreen"; 3r33581. import UserScreen from "./UserScreen"; 3r33581. import DasModalScreen from "./DasModalScreen"; 3r33581. 3r33581. const routeMap = {
Home: {3r33581. component: HomeScreen,
path: "/",
exact: true
}, 3r33581. Second: {3r33581. component: SecondScreen,
path: "/second"
}, 3r33581. User: {3r33581. component: UserScreen,
path: "/user /: name?", 3r33571. exact: true
}, 3r33581. DasModal: {
component: DasModalScreen,
path: "* /dasmodal", 3r33571. modal: true
}
}; 3r33581. 3r33581. class App extends Component {
render () {
return (3r? 3581. 3r? 3377. 3r? 3581. 3r? 3245. 3r? 3581. {WebRoutesGenerator ({routeMap})} 3r? 3581. 3r3434. 3r33581. 3r33380. 3r33581.); 3r33581.}
}
3r33581. export default App; 3r33515. 3r3494. 3r33565.  3r33581. Here is 3r???. App.js 3–3–3515. for React Native applications. Here is used for navigation 3r31414. react-navigation . 3r33565.  3r33581. 3r33565.  3r33581.
  3r???. //App.js - React Native
3r33581. import React, {Component} from "react"; 3r33581. import {3r33581. createStackNavigator,
createBottomTabNavigator
} from "react-navigation"; 3r33581. import HomeScreen from "./HomeScreen"; 3r33581. import DasModalScreen from "./DasModalScreen"; 3r33581. import SecondScreen from "./SecondScreen"; 3r33581. import UserScreen from "./UserScreen"; 3r33581. 3r33581. const HomeStack = createStackNavigator ({
Home: {screen: HomeScreen, navigationOptions: {title: "Home"}}
}); 3r33581. 3r33581. const SecondStack = createStackNavigator ({
Second: {screen: SecondScreen, navigationOptions: {title: "Second"}},
User: {screen: UserScreen, navigationOptions: {title: "User"}}
}); 3r33581. 3r33581. const TabNav = createBottomTabNavigator ({3r-3581. Home: HomeStack, 3r-?381. SecondStack: SecondStack 3r-?33581.}); 3r33581. 3r33581. const RootStack = createStackNavigator (3r3353581. {3r353581. Main: TabNav, 3r3353581. DasModal: DasModalScreen
},
{
mode: "modal",
mode: "modal",
3r33581. 3r33581. class App extends Component {
render () {
return ; 3r33581.}
}
3r33581. export default App; 3r33515. 3r3494. 3r33565.  3r33581. So, I created a simple application template and prepared a platform for further work. You can try this template, looking at 3r33531. this repository 3r33565.  3r33581. 3r33565.  3r33581. Now we will slightly complicate this pattern, we will add a routing /navigation system. 3r33565.  3r33581. 3r33565.  3r33581. 3r3-3549. 3r33550. Navigation problems and solutions 3r???. 3r33565.  3r33581. An application, unless it consists of a single screen, needs some kind of navigation system. Now (we are talking about September 2018) there is only one such universal working system suitable for the web and for native applications. It is about React Router . For the web, this solution fits well, but in the case of React Native-projects, things are not so straightforward. 3r33565.  3r33581. 3r33565.  3r33581. In React Router Native there are no transitions between screens, no support for the Back button (for the Android platform), no modal screens, navigation bars and other features. Other navigation tools like React Navigation , have these opportunities. 3r33565.  3r33581. 3r33565.  3r33581. I used this particular library, but you can pick up something else. Therefore, in my project, React Router is responsible for navigation in the web application, and React Navigation is responsible for navigation in the native application. This, however, creates a new problem. The fact is that the approaches to navigation and to the transfer of parameters in these systems are very different. 3r33565.  3r33581. 3r33565.  3r33581. In order to preserve the spirit of React Native Web, using an approach close to that used in native applications, I approached the solution of this problem by creating web routes and wrapping them in HOC. This gave me the opportunity to create an API resembling React Navigation. 3r33565.  3r33581. 3r33565.  3r33581. This approach allowed me to move between the screens of the web application, eliminating the need to create separate components for two types of applications. 3r33565.  3r33581. 3r33565.  3r33581. The first step in implementing this mechanism is to create an object with a description of the routes for the web application: 3r-3565.  3r33581. 3r33565.  3r33581.
  3r???. import WebRoutesGenerator from "./NativeWebRouteWrapper"; //self-developed function that generates React Router routes and wraps them in HOC
const routeMap = {
Home: {3r33581. screen: HomeScreen,
path: '/',
exact: true
}, 3r33581. Menu: {3r33581. screen: MenuScreen,
path: '/menu /sectionIndex?' 3r33581.}
}
//in the render method
3r33581. {WebRoutesGenerator ({routeMap})}
3r33380. 3r33515. 3r3494. 3r33565.  3r33581. In essence, here is a copy of the function to create the React Navigation navigatoradditions of features specific to the React Router. 3r33565.  3r33581. 3r33565.  3r33581. Further, using my auxiliary function, I create routes 3r33514. react-router and wrap them in a hoc. This allows you to clone the component 3r33514. screen and add 3r?314. navigation in its properties. This approach mimics the behavior of React Navigation and makes methods like 3r33514 available. navigate () , 3r???. goBack () , 3r???. getParam () . 3r33565.  3r33581. 3r33565.  3r33581. 3r3-3549. 3r33550. Modal screens 3r???. 3r33565.  3r33581. React Navigation, thanks to createStackNavigator , makes it possible to make sure that a certain page of the application leaves the bottom in the form of a modal screen. In order to achieve this in a web application, I had to use the library. React Router Modal . To work with a modal screen, you first need to add the appropriate option to the object 3r33514. routeMap 3r33535. : 3r33565.  3r33581. 3r33565.  3r33581.
  3r???. const routeMap = {
Modal: {
screen: ModalScreen,
path: '* /modal',
modal: true //the router will use the ModalRoute component to render this route
}
} 3r33515. 3r3494. 3r33565.  3r33581. In addition, in the layout of the application you need to add the component 3r33514. 3r3r434. 3r33515. from the library 3r?314. react-router-modal . The corresponding page will be displayed there. 3r33565.  3r33581. 3r33565.  3r33581. 3r3-3549. 3r33550. Navigation between screens 3r???. 3r33565.  3r33581. Thanks to our development HOC (temporarily this component is called NativeWebRouteWrapper , And this is a terrible name, by the way), we can use almost the same set of functions as in React Navigation to organize navigation between pages in the web version of the application 3r33565.  3r33581. 3r33565.  3r33581.
  3r???. const {product, navigation} = this.props
3rr3461. onPress = {navigation.navigate ('ProductScreen', {id: product.id})}
title = {`Go to $ {product.name}`}
/> 3r33581. 3rr3461. onPress = {navigation.goBack}
title = "Go Back"
/> 3r33515. 3r3494. 3r33565.  3r33581. 3r3-3549. 3r33550. Returns to the previous screen 3r33551. 3r???. 3r33565.  3r33581. In React Navigation, you can go back to n 3r33515. screens that are in the navigation stack. Similar to the React Router is not available, there is no navigation stack. In order to solve this problem, we need to import the function 3r33514 into the code. pop self-developed. Calling her, we will give her several parameters: 3r33535.  3r33581. 3r33565.  3r33581.
  3r???. import pop from '/NativeWebRouteWrapper /pop'
render () {
const {navigation} = this.props
return (
3r33581.) 3r33581.} 3r33515. 3r3494. 3r33565.  3r33581. We describe these parameters:
 3r33581. 3r33565.  3r33581. 3r301501.  3r33581. 3r? 3513. 3r???. screen - screen name (used by React Router in the web version of the application). 3r? 3516.  3r33581. 3r? 3513. 3r???. n 3r33515. - number of screens to return using the stack (using React Navigation). 3r? 3516.  3r33581. 3r? 3513. 3r???. navigation - The object that provides navigation. 3r? 3516.  3r33581. 3r33518. 3r33565.  3r33581. 3r3-3549. 3r33550. Results of work 3r33551. 3r???. 3r33565.  3r33581. If you want to experiment with the idea of ​​developing universal applications presented here, I created two templates. 3r33565.  3r33581. 3r33565.  3r33581. 3r? 3531. The first 3r36969. It is a pure universal environment for developing web applications and native applications. 3r33565.  3r33581. 3r33565.  3r33581. 3r33537. The second is 3r3-3569. - this is, in essence, the first template, which is expanded at the expense of my system to organize navigation through the application. 3r33565.  3r33581. 3r33565.  3r33581. 3r? 3543. Here is 3r3-3569. papu demo application based on the above considerations. It is full of errors and dead ends, but you can assemble it yourself, run it in the browser and on a mobile device, and in practice get an idea of ​​how it all works. 3r33565.  3r33581. 3r33565.  3r33581. 3r3-3549. 3r33550. Results 3r33551. 3r???. 3r33565.  3r33581. The community of React-developers, of course, need a universal library for organizing navigation through applications, as this will simplify the development of projects like the one we talked about. It would be very good if the React Navigation library would work on the web (in fact, this possibility is already 3r3-3555. 3r36969 is available, but working with it is not without difficulties). 3r33565.  3r33581. 3r33565.  3r33581. 3r33561. Dear readers! 3r? 3562. Do you use React features when building generic applications? 3r33565.  3r33581. 3r33565.  3r33581. 3r? 3567. 3r3-3568. 3r? 3569. 3r? 3577. 3r33581. 3r33581. 3r33581. 3r? 3574. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33575. 3r33581. 3r? 3577. 3r33581. 3r33581. 3r33581. 3r33581.
+ 0 -

Add comment