Because the company needs to use RN to develop App, so in a new bald trip, summarized some knowledge points to sort out and share, hoping to help you.

I. Project configuration

Development environment setup: see here

1. Install react-Navigation 4.x

1-1. Route installation and configuration

  • Install core components and use component libraries

    $yarn add react-native reanimated react-native gesture-handler $yarn add react-native reanimated react-native gesture-handler React-native -screens react-native-safe-area-context @react-native community/ marshall-view react-navigation-stack $ yarn add react-navigation-drawer $ yarn add react-navigation-tabsCopy the code

    React Native 0.60 and above automatically link packages, otherwise manual link is required

  • Run pod Install in the ios directory

  • Add dependencies for the react-native Screens

    • To complete the installation on Android, you need to add dependencies for the React-native screens in Android /app/build.gradle

      implementation 'androidx. Appcompat: appcompat: 1.1.0 - rc01'
      implementation 'androidx. Swiperefreshlayout: swiperefreshlayout: 1.1.0 - alpha02'
      Copy the code
  • Configure the react – native – gesture – handler

    To be able to use react-native Mouth-Handler on Android, mainActivity.java needs to be modified.

    package com.reactnavigation.example;
    
    import com.facebook.react.ReactActivity;
    + import com.facebook.react.ReactActivityDelegate;
    + import com.facebook.react.ReactRootView;
    + import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
    public class MainActivity extends ReactActivity {
    
      @Override
      protected String getMainComponentName(a) {
        return "Example";
      }
    +  @Override
    +  protected ReactActivityDelegate createReactActivityDelegate(a) {+return new ReactActivityDelegate(this, getMainComponentName()) {
    +      @Override
    +      protected ReactRootView createRootView(a) {+return new RNGestureHandlerEnabledRootView(MainActivity.this); + +}}; +}}Copy the code
  • Import react-native Mouth-handler in index.js

1-2. Two ways to obtain route parameters

  • this.props.navigation.state.paramsGets the entire parameter object
  • This. Props. Navigation. GetParam (' name ')Obtain parameters by key

2. Configure the Icon library

  • Install YARN add react-native vector-icons

  • The configuration of ios

    Add the following code to info.plist in the ios directory

    <key>UIAppFonts</key>
    <array>
      <string>AntDesign.ttf</string>
      <string>Entypo.ttf</string>
      <string>EvilIcons.ttf</string>
      <string>Feather.ttf</string>
      <string>FontAwesome.ttf</string>
      <string>FontAwesome5_Brands.ttf</string>
      <string>FontAwesome5_Regular.ttf</string>
      <string>FontAwesome5_Solid.ttf</string>
      <string>Foundation.ttf</string>
      <string>Ionicons.ttf</string>
      <string>MaterialIcons.ttf</string>
      <string>MaterialCommunityIcons.ttf</string>
      <string>SimpleLineIcons.ttf</string>
      <string>Octicons.ttf</string>
      <string>Zocial.ttf</string>
      <string>Fontisto.ttf</string>
    </array>
    Copy the code
  • Run pod Install in the ios directory

  • Configure the android

    Edit the Android /app/build.gradle file and add the following code

    apply from: ".. /.. /node_modules/react-native-vector-icons/fonts.gradle"
    Copy the code

3. Local storage AsyncStorage

The original official API is obsolete. You are advised to use the following extensions

AsyncStorage: yarn add @react-native async-storage/async-storage

4. Configure the UI library

The UI library used in the project is the React Native Elements document address

Second, Code Push hot update

App Center Official CLI document

React NativeCLient Official SDK documentation

Reference Collation 2

Currently codepush.appCenter. ms/ services are blocked, which may cause heat more…

1. Project configuration

1-1. Configure the server

  • Install the App Center CLI to manage server information

    $ sudo yarn global add appcenter-cli
    Copy the code
  • Log in the app center

    $ appcenter login
    Copy the code
  • Run the above command and confirm in the command line, the web page will pop up a login page, login, you will get a string of Access code, copy and paste back to the command line, successful login account will be returned.

    $ appcenter login Opening your browser... ? [Visit]:https://appcenter.ms/cli-login? hostname=assetfundeMacBook-Pro.local and enter the code: ? Access code from browser: 0cd185da****36a****7295b3****c8da9ba766a LoggedinAs Xuechongcommodity hotmail.comCopy the code
  • Add the App information. Here, add Android and iOS(I lowercase) respectively. The App name is HbH5App, for example

    // -d is followed by the name of the app display, // -o stands for operation Android/iOS // -p stands for Platform react-native $AppCenter apps create -d HbH5App-android -o Android -p React-Native $ appcenter apps create -d HbH5App-ios -o iOS -p React-NativeCopy the code
  • Next, run the AppCenter Apps List to check if it was added successfully

    $ appcenter apps list
    xuechongwei-hotmail.com/HbH5App-android
    xuechongwei-hotmail.com/HbH5App-ios
    Copy the code
  • You can deploy a hot update service to an added app. Generally, two updates are deployed for grayscale updates, one is Staging and the other is Production. Deployed separately for Android and iOS, so it takes four lines of command to run

    // a is for application, // Deploy IOS $AppCenter codePush Deployment add -a xuechongwei-hotmail.com/HbH5App-ios Staging $AppCenter Codepush Deployment Add-a xuechongwei-hotmail.com/HbH5App-ios Production // Deploy Android $AppCenter codepush Deployment Add-a  xuechongwei-hotmail.com/HbH5App-android Staging $ appcenter codepush deployment add -a xuechongwei-hotmail.com/HbH5App-android ProductionCopy the code

1-2.IOS and Android configuration

Install dependency packages: yarn add react-native code-push

Ios Configuration


  • Switch to the ios directory and run pod Install

  • Open the appdelegate.m file and add the following code

    #import <CodePush/CodePush.h>
    Copy the code
  • Find the following code and replace it

    return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; // replace return [CodePush bundleURL];Copy the code
  • Change the value of the CodePushDeploymentKey tag in the/project directory /ios/ Project name/info.plist file. (If not, add one)

    <key>CodePushDeploymentKey</key>
    <string>Rbw0ct6cIQS******sKb0laMQNMVju</string>
    Copy the code
  • Change the version number versionName (set to 1.0.0)

Android Configuration method


  • In the Android /settings.gradle file, add the following code

    include ':app'.':react-native-code-push'
    project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '.. /node_modules/react-native-code-push/android/app')
    Copy the code
  • In the Android /app/build.gradle file, add the following code:

    . apply from:".. /.. /node_modules/react-native/react.gradle"
    apply from: ".. /.. /node_modules/react-native-code-push/android/codepush.gradle"- > new...Copy the code
  • Modify the MainApplication. Java

    .// 1. Import the CodePush plug-in class
    import com.microsoft.codepush.react.CodePush;
    
    public class MainApplication extends Application implements ReactApplication {
        private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {...// 2. Add this code
            @Override
            protected String getJSBundleFile(a) {
                returnCodePush.getJSBundleFile(); }}; }Copy the code
  • Add the deployed key to the strings. XML file

    <string moduleConfig="true" name="CodePushDeploymentKey">The real key</string>
    
    <! -- Check the deployment key-->
    appcenter codepush deployment list -a <ownerName>/<appName> <deploymentName>-k Example: AppCenter codePush Deployment list -a xuechongwei-hotmail.com/HbH5App-android -kCopy the code
  • Example Change the version number versionName

    Open the android/app/build gradle, search defaultConfig positioning to the following code, modify the versionName as 1.0.0 (the default is 1.0, codepush need three digits)

    android{
        defaultConfig{
            versionName "1.0.0"}}Copy the code

2. Common commands

Older code push command


$code-push release-react GithubRN -ios IOS --t 1.0.0 --devfalse --d Production --des "1. Submit information" --m true$code-push Deployment ls githubrn-android $code-push deployment ls githubrn-androidhistoryAppName Staging/Production check the deployment key: $code-push deployment ls [APP_NAME] -kCopy the code

New appCenter command


$appCenter codePush Deployment list -a <ownerName>/<appName> Example: AppCenter codePush Deployment List -a xuechongwei-hotmail.com/HbH5App-ios -k // Release new version: By default, updates are pushed to the Staging deployment. // Specify the version: $AppCenter codePush release-react-a xuechongwei-hotmail.com/HbH5App-ios -d Production -t 1.0.0 --description'Update content'$appCenter codePush release-a xuechongwei-hotmail.com/HbH5App-ios --description'update'// Force update // add -mtrueThe default effect of forced update is that when you popup to confirm the update, there is only the confirm button, and it takes effect immediately after the successful installation, so the app may blink. $ appcenter codepush release-react -a xuechongwei-hotmail.com/splashExample-ios -mtrue  --description 'update'$appCenter codePush Deployment $appCenter codePush Deploymenthistory-a <ownerName>/<appName> <deploymentName> // Displays history $AppCenter codePush Deploymenthistory-a xuechongwei-hotmail.com/HbH5App-ios Staging // Clearing history $AppCenter codePush Deployment clear Staging -a xuechongwei-hotmail.com/HbH5App-iosCopy the code

3. Configure the update mode

import {AppRegistry} from 'react-native';
import CodePush from 'react-native-code-push';
// In silent mode, the app checks for updates to 'ON_APP_RESUME' every time it starts.
const codePushOptions = {checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME};

// Manually receive updates
//const codePushOptions = { checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME };
import _App from './App';
const App = CodePush(codePushOptions)(_App);
import {name as appName} from './app.json';
Copy the code

4. The deployment of code – push – server

Microsoft cloud service is too slow in China, and some services are blocked, so hot update cannot be performed normally. You are advised to deploy the update server by yourself. Reference documentation

Third, technical points

Other knowledge points

1. Check the ios screen

  • Official DeviceInfo is about to be deprecated. You can use deviceInfo.isiphonex_deprecated to determine whether the device is deprecated

  • You can install the following extension :react-native device-info You can check by deviceinfo.hasnotch ()

  • Use the aspect ratio of the screen to determine that a value greater than 1.8 is a full screen

2. The navigation level cannot be redirected

  • Route jump is extracted to NavigatorUtil.js

    In the HomePage add NavigationUtil render method to the main entrance to the file. The navigation = this. Props. Navigation;

    Call navigation of the corresponding page

3. Notes on iOS border rounded corners

Please note that the following rounded border styles are not currently supported on the iOS Image component:

  • borderTopLeftRadius
  • borderTopRightRadius
  • borderBottomLeftRadius
  • borderBottomRightRadius

4. Pay attention to the image URL

For the new image resource mechanism to work properly, the image name in require must be a static string (no variables! Because require is executed at compile time, not run time! . Refer to the address

/ / right < Image source = {the require (". / my - icon. PNG ")} / >; // const icon = this.props. Active? "my-icon-active" : "my-icon-inactive"; <Image source={require("./" + icon + ".png")} />; // const icon = this.props. Active? require("./my-icon-active.png") : require("./my-icon-inactive.png"); <Image source={icon} />;Copy the code

5. Determine the development environment

Determine the development environment by using the global variable __DEV__

6. Pack the Android and ios installation packages

Pack Android: Reference address

Package iOS: Reference address

  • Reference address for ios certificate application

  • Ios packaging considerations

    Archive is packaged through Product -> Archive, and the Archive result page is opened through Window -> Organizer for export

7. Check the version of the mobile phone

import {Platform} from 'react-native';

// On Android, the Version attribute is a number representing the Android API level:
if (Platform.Version === 25) {
  console.log('Running on Nougat! ');
}

// on iOS, the Version attribute is the return value of -[UIDevice systemVersion], in the form of a string representing the current systemVersion. For example, it could be "10.3".
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
  console.log('Work around a change in behavior');
}
Copy the code

8. Screen adaptation

1. Simple unit conversion

Take a 750 width design draft as an example:

If you want 750 to represent the width of an RN device, you can design your code like this:

const viewPortWidth = 750; Const px2dp = (px: number): number => { return px * Dimensions.get('window').width / viewPortWidth } <View style={{height:200,width:px2dp(750),backgroundColor:'yellow'}}> <Text>750</Text> </View>Copy the code

2. Third-party library Reference ADDRESS 1 Reference address 2

The following libraries are recommended: Github address

// install yarn add react-native adaptive stylesheet // import stylesheet from 'react-native adaptive stylesheet'; StyleSheet.setGuidelineBaseWidth(750); StyleSheet. Configure ({width: 375, scaleFont: true,}); <View style={{width: StyleSheet. ScaleView (60)}}> StyleSheet.scaleFont(18) }}>This is am example! StyleSheet. Create ({container: {width: 375, borderWidth: StyleSheet.hairlineWidth, fontSize: 18, }, });Copy the code

9. Set the route switching effect of Android to ios mode

React-navigation4.x reference documentation

import { TransitionPresets } from 'react-navigation-stack'; {// Route configuration... }, { initialRouteName: 'Index', defaultNavigationOptions: { ... TransitionPresets.SlideFromRightIOS, }, }Copy the code

10. Get the element position size

<View ref={(filter) => (this.filter = filter)}></View> this.filter && this.filter.measure((x, y, width, height, left, top) => { console.log('===x===', x); // The X coordinate of the component relative to the parent layout? console.log('===y===', y); // The Y coordinate of the component relative to the parent layout? console.log('===width===', width); // Width of component console.log('===height===', height); // Height of the component console.log('===left===', left); Console. log('===top===', top); // The component's Y coordinates on the screen});Copy the code

11. Animation tutorial

The official documentation

Jane’s book

12. Integrate Redux Dev Tools

To be redux-Thunk compliant, you need to use enhanced functions for processing

import { createStore , applyMiddleware ,compose } from 'redux'  // Introduce the createStore method
import reducer from './reducer'    
import thunk from 'redux-thunk'

const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose

const enhancer = composeEnhancers(applyMiddleware(thunk))

const store = createStore( reducer, enhancer) // Create a datastore
export default store   // Expose
Copy the code

13. No landscape

  • The Android end

    / / add the android: screenOrientation = "portrait"Copy the code

    ! [] (gitee.com/thelife/pic… 15.14.52. PNG)

  • The IOS side

    In the Xcode project, uncheck the corresponding check box

14. Declare global variables

global.vars = {
   website:'http://www.baidu.com'.name:"Baidu"};// call from the entry file index.js, and then use it globally
import './globalVariable.js';
<Text>{global.vars.name}</Text>
Copy the code

15. Shadow scheme

  • IOS shadow implementation scheme

    RN supports a set of shadow style attributes on ios, but these attributes do not work on Android. Container: {shadowColor: '#000', shadowOffset: {width: 0, height: 2}, shadowRadius: 2, shadowRadius: 0.2}Copy the code
  • Android shadow implementation scheme

  • <View elevation={2} style={styles.container}> <Text>Hello World ! </Text> </View> container : { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowRadius: Opacity: 0.2, elevation: 2}Copy the code

16. Disable android keyboard jacking elements

The AndroidManifest. XML file find android: windowSoftInputMode: its value changed to stateAlwaysHidden | adjustPan (original value adjustResize)

17.Touchable series components do not respond well

Sometimes, if we have an action that happens in the same frame as the transparency change or highlight effect from the click, we may not see it until the end of the onPress function. For example, a setState operation is performed in onPress, which requires a lot of computation and causes frames to drop.

handleOnPress() {
  requestAnimationFrame(() => {
    this.doExpensiveAction();
  });
}
Copy the code

Optimization 18.

React rerenders components when internal state or externally passed props change. A large number of components that have to be rerendered in a short period of time can cause serious performance problems.

  • Use PureComponent to allow components to compare their props changes to control rendering times. In practice, this is a more controlled approach than purely functional components. Or use shouldComponentUpdate in the Component to control the update/re-rendering of the Component via conditional judgment.

  • When using PureComponent, note that the component is in shallow comparison state. If there are a lot of reference objects for the props, the internal changes of those objects will not be compared. Avoid complex data structures when writing code

  • Fine-grained components, split dynamic/static components. Unified planning is required after the project is stable and has a certain scale.

  • Learning immutable – js

    Zhihu reference materials

RN interacts with the webView

//RN uses injectJavaScript and injectedJavaScript to inject webViewjs // uses onMessage to listen for messages from HTML pages onMessage(event) { console.log(event.nativeEvent.data) } <WebView ref={(webView) => (this.webView = webView)} source={{uri: This.state. url}} userAgent={this.state.ua} onMessage={this.onmessage. bind(this)} injectedJavaScript={// Inject code} Then ((res) => {const jsCode = '(function() {const jsCode =' (function() { window.newAppUserInfo = ${res}; }) (); `; this.webView.injectJavaScript(jsCode); }); this.setState({loading: false}); }} / > / / HTML page by calling the following methods to send data to the RN window. ReactNativeWebView. PostMessage (' string data)Copy the code

20. Turn on the gesture to return

This function is enabled by default on ios and manually on Android

 navigationOptions: {
 	gestureEnabled: false,
 },
Copy the code

21. Pass the parameter modification page animation

NavigationOptions: ({navigation}) => ({navigation}) navigationOptions: ({navigation}) => ({... 'DefaultTransition' : 'SlideFromRightIOS'],}),},Copy the code

22. The display of Android RMB symbol is abnormal

This is because of the full Angle and half Angle, full Angle ¥will be affected by the system, while half Angle ¥is basically not affected

  1. The input method is usually switched to Chinese input methodshift + 4And half a dime works on the MACoption + YKnock out
  2. Using the HTML special symbol, ¥is rewritten asselections

4. Common problems

1. Multiple dependent Android parsing conflicts

2. Ios dependency resolution error

Try switching to the ios directory and executing pod Install

3. Emulator error pop-ups do not disappear

Sometimes the emulator error popup window is caused by code error. After restoring the code, the error popup window still exists. Try the following:

  • Close all terminal Windows
  • Project root start terminal, runyarn cache cleanAnd then start the project

4. The TextInput text is not displayed completely

For problems under Android, add style paddingVertical: 0

5. How to debug HTTP requests

Note: It is currently impossible to detect network requests in React Native using Chrome debugging. You can use a third-party react-Native debugger to do this.

6. Measure returns undefined

If a View is only used to lay out its child components, it may be removed from the native layout tree for optimization, resulting in some functions being called on the component with unexpected results. Setting Collapsable to false disables this optimization to ensure that the corresponding view exists in the native structure.

7. Android can’t capture packets

The solution

8. Webview cannot automatically play H5 music

/ / add the following two attributes to the webview mediaPlaybackRequiresUserAction = {false} / / do not require users to click on the trigger mixedContentMode = "compatibility" // Prevents music resources and domain names from being played due to different protocols (HTTP and HTTPS)Copy the code