In React Native, due to business requirements, we often need to transfer and manage some parameters between many pages and components. Here I summarize several proven, stable and user-friendly methods for you

React Navigation Transmits values

Recommended index: ♥ ♥ ♥ ♥

Application scope: Transfer values between adjacent pages

Compatibility: IOS/Android principle: React Navigation mounts a Navigation object on the props of the page, which can be used for route jump. When performing a page jump, the user can carry parameters or callback methods to the target page to transfer parameters

Note: This is the official recommendation, and we use the most in business development, the most respected one of the way to pass parameters, the idea is similar to the Web in QueryString jump with parameters, but the implementation is slightly different, for example:

Navigation by value can be positive by value, also can reverse the value For example A - > B is positive value, and B - > is reversed by value Positive transfer value: A page jump to page B, within the component by visiting this. Props. Navigation. Navigate ('B', { 
   type: 'list',         
   callback:data => { console.log('data in callback: ', data); }}); You can get the value in the component's lifecycle function on the B pagecomponentWillMount() {
    const { state: { params: { type, callback }, goBack }} = this.props.navigation;
    console.log('type: '.type);
    // type 'list'} backpass: if you want to goBack to the previous page, manually call callback, pass the parameter to it, and then call goBack. Const {state: {params: {goBackToPageA: () => {const {state: {params: {type, callback }, goBack }} = this.props.navigation;
    callback({ id: '123', message: type + ' really? '}); goBack(); } goBackToPageA(); Go back to page A'data in callback: ', { id: '123', message: 'list really? '}); The data argument in callBack is {id:'123', message: 'list really? '}

Copy the code

DeviceEventEmitter fires events and transmits values

Recommended index: ♥ ♥ ♥

Application scope: Value transfer between pages/components

Compatibility: IOS/Android

React Native uses the DeviceEventEmitter module provided with the React Native package to subscribe to events, trigger events, and transmit values

Description: DeviceEventEmitter, as its name indicates, transmits values based on the mechanism of event subscription. When an event is subscribed, the callback of the subscribed event will be called when triggered, and the value can be sent to the other groups in the same page. Values can be passed between different pages, but only if the page has not been destroyed (the subscription to the event will be cancelled after the destruction), for example:

DeviceEventEmitter.addListener('warning_event', (data) => { console.log('data: ', data); }) DeviceEventEmitter.emit('warning_event', { name: 'Mega Galaxy'}); // data: {name: 'Mega Galaxy'} after emit the event, the input to the callback function becomes {name: 'Mega Galaxy'}, callback is undefined if no value is passedCopy the code

Disadvantages: The essence is the listening and triggering of custom events. When the page logic is complex, the amount of code will increase, the maintenance cost will be high, and the excessive listening will cause performance problems. Another point is that the listening must be removed when the page is destroyed: what if you forget to remove the listening? Then each emit event will respond one more time to the listener you added

componentDidMount() {
    this.eventHandler = DeviceEventEmitter.addListner('event_name', callback);
}
componentWillUnmount() {
    this.eventHandler.remove();
}
Copy the code

Personal advice: After sorting out the logic of the page, use it wisely

AsyncStorage key-value parameter transfer

Recommended index: ♥ ♥ ♥

Scope: Arbitrary parameter passing across pages and components

Compatibility: IOS/Android

Principle: Using the idea similar to localStorage in the Web, store the parameters/data in AsyncStorage, and then take out the necessary place to use

Description: We all know the practicality and popularity of localStorage in the Web. AsyncStorage is actually the RN version of localStorage, with a slight difference that it is asynchronous, Only promises are returned, so pairing with async/await is very useful

SaveOrderData = async () => {try {const orderData = [{id: 1, data: []}, {id: 2, data: [] }] await AsyncStorage.setItem('Order_data_cache', JSON.stringify(orderData )); } catch (error) {// error saving data}} loadOrderData = async () => {const __orderData = await AsyncStorage.getItem('Order_data_cache'); const orderData = JSON.parse(__orderData); this.setState({ orderData }); }Copy the code

Disadvantages: Key-value storage parameter transmission may focus on data storage, and because it involves I/O operations, there is the possibility of lag on some low-end models

React Context Api 传参(新版Context Api)

Recommended index: ♥ ♥ ♥

Scope: Components in different pages share data from a common class

Compatibility: IOS/Android

Principle: Use the generated data warehouse to wrap the parent component, and then get the data in the data warehouse from the child component

Note: The Context Api is a useful tool for managing logged-in user data with common attributes, but it can be quite cumbersome to use

  const ContextWrapper = React.createContext();
  <ContextWrapper.Provider value={{ name: 'Mega Galaxy', job: 'FrontEnd Engineer'}} <App /> < contextwrapper. Provider> // <ContextWrapper.Counsumer> { context => <Text> { context.name } { context.job }</Text> } </ContextWrapper.Counsumer> => <Text> Mega Galaxy FrontEnd Engineer </Text>Copy the code

Cons: Takes some effort to understand, is cumbersome to write, is suitable only for certain types of data, and is clear about the wrapping relationships between components

Global spread value

Recommended index: ♥ ♥ ♥

Scope of application: value transfer between pages (global any page)

Compatibility: IOS/Android

How to use node.js’s top-level object — Global. To mount properties and use properties to pass values

In front of the jump page, you can mount the parameters to be passed on the Global object. After the jump, you can access the key on the Global object to get the corresponding value, for example:

Global. Params = {name: 'Jalon', id: '123456'} '123456'} In addition to strings, booleans, objects, and arrays, functions can also be passed. If the passed function has variables that reference the context of the component, decouple it, otherwise an error may be reported.Copy the code

Disadvantages: If too many mounted attributes/methods may cause conflicts and pollution, it is not conducive to maintenance. Personal advice: Use it only when react-Navigation jump value transfer and DeviceEventEmitter are inconvenient to maintain, but use it as little as possible to avoid pollution and conflict of global attributes

Summarize 5 common methods of parameter/data passing, from a personal perspective, The recommended sequence is React Navigation > DeviceEventEmitter triggering events and transmitting values > AsyncStorage key-value. The last two types are used only in special scenarios. Therefore, choosing the right way to transmit values in the right scenario will bring twice the result with half the effort in the development of React Native project.