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.params
Gets the entire parameter objectThis. 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
- The input method is usually switched to Chinese input method
shift + 4
And half a dime works on the MACoption + Y
Knock out - Using the HTML special symbol, ¥is rewritten as
selections
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, run
yarn cache clean
And 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