The purpose of React Native is to “learn once and write anywhere”. Facebook hopes that people can learn once and use everywhere. However, it is not as easy as expected to transplant the same JS code from front-end to RN or RN to front-end. In fact, in addition to the same syntax, there are many differences, so we can not do direct copy, the following is my experience in migrating code, summed up some

1 Antd Mobile

Ant Financial of Antd Mobile has an open source SET of UI components, which has realized the unified UI of front-end, iOS and Android, and we recommend you to use it more

1.1 the Flex

1.1.1 Using Flex Parameters

Use direction justify align because some mobile browsers do not support Flex. Antd does this for me, but it does not work:

Good:

<Flex  direction="column" align="start" justify="startt">
Copy the code

Bad :(this writing does not take advantage of the Flex adaptation)

<Flex style={{  
flexDirection: "column",  
backgroundColor: "white",
justifyContent: "flex-start"}} >Copy the code

In this case, you need to write a lot of adaptive CSS code because of front-end compatibility, for example

{
      display: flex;
      display: -webkit-flex;
      flex-direction: row;
      -webkit-flex-direction: row;
      justify-content: flex-start;
      -webkit-justify-content: flex-start;
      align-items: center;
      -webkit-align-items: center;
}
Copy the code

1.1.2 Displaying the specified flexDirection

Because Flex is not available in some cases, for example, the Touchable component on the RN side can only wrap native components. Flex must be replaced by View, and the default orientation of View and Flex is different. Therefore, display the flexDirection to clearly inform the direction and make it easier for the migrator to change the code

Good:

<Flex  direction="column"> {... } </Flex>Copy the code

Bad :(wrong direction when replaced with View)

<Flex> {... } </Flex>Copy the code

1.2 a ListView

In RN 0.51, antD’s ListView will report an error. We still use the ListView provided by RN. We just need to modify the import ListView

Import {ListView} from is not recommended"antd-mobile"; Import {ListView} from is recommended"react-native";
Copy the code

2 Code Specification

2.1 Try to be componentized

A common way to write complex pages is to split the page into several moduleRender functions, each of which is called separately in the Render function, similar to the following

Bad:

class SomeComponent extends Component {
      renderSubOne() {
        return<Flex>{... }</Flex>; }renderSubTwo() {
        return<Flex>{... }</Flex>; }renderSubThree() {
        return<Flex>{... }</Flex>; }render() {
         return <Flex>
            {this.renderSubOne()}
            {this.renderSubTwo()}
            {this.renderSubThree()}
          </Flex>
      }
}
Copy the code

Good:

  1. Because a migration is likely to be one part of a migration, try to break it down into components to make it more flexible
  2. In this way, the performance is higher. When written separately, each component has its own life cycle and the refresh of a child component does not affect the parent component
class SomeComponent extends Component {
      render() {
         return <Flex>
            <SubOne />
            <SubTwo />
            <SubThree />
          </Flex>
      }
}
Copy the code

2.2 Don’t use CSS

There’s a significant difference between RN and the front end of the style RN:

import { StyleSheet } from "react-native";

const styles = StyleSheet.create({
 someContainer: {
    fontSize:16,
    fontWeight: 'bold',},... }) <Flex style={styles.container} />Copy the code

Front end:

// import CSSModules from'react-css-modules'; . @CSSModules(styles) ... <Flex className="someContainer">
Copy the code
// CSS file.somecontainer {font-size: 16px; font-weight: bold; }Copy the code

You can see from the above example

  1. The front-end style is hidden in the CSS file, migration needs to find one by one
  2. Font size,fontSize

These differences need to be manually modified when we migrate, which is a lot of work

The recommended way to write this is to write RN uniformly:

// Front-end js file const styles = {// There is no need to use stylesheet. create someContainer: {fontSize:16, fontWeight:'bold',},... } <div style={styles.container} />Copy the code

2.3 Third-party Components

Be careful when selecting third-party components

  1. Use native, or ANTD, whenever possible
  2. Choose to support front-end and mobile devices as much as possible
  3. Try to choose something that is maintained
  4. If git is not maintained or is old, it is recommended to copy the code instead of using NPM. Because RN and React versions are updated, it is often necessary to manually modify part of the code to run. Therefore, it is convenient to copy the code directly to the project

3 differences

Some of these differences are natural differences between the front end and RN and need to be noted

3.1 the Image

Loading image resources is written differently at both ends and needs to be manually modified

Front end:

<img style={{ width: 98, height: 82 }} src={nullImg} alt="nullImg" />
Copy the code

RN:

<Image style={{ height: 15, width: 15, marginLeft: 10 }} source={{ uri: 'search3'}} / >Copy the code

3.1.1 RN) Image

Note that after React Native 0.50.3, the Image component can no longer wrap the child

<Image> // 0.50.3 <Image> child... } </Image>Copy the code

If you really need to, you can only use absolute position

3.2 the Text Text

The front-end rendering Text has a variety of labels, such as div and SPAN, but there is only one Text at the RN end, which will bring a lot of work in migration. The Text is scattered everywhere and needs to be replaced one by one manually. React-intl is recommended. The RN side is react-Intl-native, a third-party component provided by Yahoo, which can unify the front-end and RN side

Bad:

<div> text </div> <span>Copy the code

Good:

  <FormattedMessage
    style={styles.valueDesc}
    id="someId"
    defaultMessage={text}
  />
Copy the code

3.3 Response Events

Front end:

/ / you can add on any tag < div onclick = {() = > {}} / > < img onclick = {() = > {}} / >Copy the code

RN:

<TouchableHighlight onPress={}>// Can have only one child and must be RN native, Cannot be a custom component <View> // Want to wrap more elements with a View {child} </View </TouchableHighlight>Copy the code

As you can see from the above, click event migration often requires a lot of code change

  1. Add the TouchableHighlight tag
  2. If you have more than one child tag, then you need to add a View to nest it and keep the style unchanged
  3. The onClick to onPress

3.4 Route Redirection

  • Front end usereact-route
  • RN might have different options depending on the situation, for examplereact-navigation.react-native-navigationEtc.

There will be different writing methods, need to migrate according to the specific selection of libraries, manual modification

3.5 PropTypes

PropTypes is a type-checking tool provided by React, but as versions have changed since React 15.5, PropTypes has been moved out of React to form a separate library, which may require extensive manual modification if the front-end and RN versions do not match

// react version < 15.5 import react, {Component, PropTypes} from'react'; // react version >= 15.5 import react, {Component} from'react';
import PropTypes from 'prop-types';
Copy the code

3.6 Global Variables

The front-end JS code is usually run in a browser. The browser itself provides the window global variable, but RN does not, so do not use the window global variable in the front-end, but use an import file instead

Bad:

window.someVar = var
Copy the code

Good:

// Create a constants.js file const object = {website:'http://www.hao123.com',
   name:Good '123'};exportdefault object; // Import Import constants from when needed'./constansts.js'
<Text>{constants.name}</Text>
Copy the code