Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Designing and maintaining an open-source React Native library

Designing and maintaining an open-source React Native library

Mathieu Acthernoene

October 14, 2021
Tweet

More Decks by Mathieu Acthernoene

Other Decks in Technology

Transcript

  1. Designing and maintaining an


    open-source React Native library
    React & React Native Bordeaux

    View full-size slide

  2. Mathieu Acthernoene


    Lead front-end developer
    @
    Swan


    Podcast host
    @
    Putain de Code !

    View full-size slide

  3. Maintainer of:


    react-native-bootsplash,


    react-native-localize,


    react-native-permissions

    View full-size slide

  4. React Native isn't magical 🧙

    View full-size slide

  5. React Native isn't magical 🧙
    …The cost of cross-platform in react-native-localize

    View full-size slide

  6. What's the bridge for?
    Reading sync data using constants,


    Calling async methods using promises or callbacks,


    Receiving events using event listeners

    View full-size slide

  7. What's the bridge for?
    Reading sync data using constants,


    Calling async methods using promises or callbacks,


    Receiving events using event listeners

    View full-size slide

  8. - (NSDictionary *)constantsToExport {


    return @{


    @"initialTimeZone": [[NSTimeZone localTimeZone] name],


    };


    }


    Objective-C TypeScript
    import { NativeModules } from "react-native";


    const NativeModule: Readonly<{


    initialTimeZone: string;


    }> = NativeModules.RNModuleTemplate;


    export const initialTimeZone =


    NativeModule.initialTimeZone;


    View full-size slide

  9. @Override


    public @Nullable Map getConstants() {


    HashMap constants = new HashMap<>();


    constants.put("initialTimeZone",


    TimeZone.getDefault().getID());


    return constants;


    }


    Java TypeScript
    import { NativeModules } from "react-native";


    const NativeModule: Readonly<{


    initialTimeZone: string;


    }> = NativeModules.RNModuleTemplate;


    export const initialTimeZone =


    NativeModule.initialTimeZone;


    View full-size slide

  10. What's the bridge for?
    Reading sync data using constants,


    Calling async methods using promises or callbacks,


    Receiving events using event listeners

    View full-size slide

  11. RCT_EXPORT_METHOD(


    getTimeZone:(RCTPromiseResolveBlock)resolve


    rejecter:(RCTPromiseRejectBlock)reject


    ) {


    @try {


    resolve([[NSTimeZone localTimeZone] name]);


    } @catch (NSException *exception) {


    reject(@"error_code", exception.reason, nil);


    }


    }


    import { NativeModules } from "react-native";


    const NativeModule: Readonly<{


    getTimeZone: ()
    =
    > Promise;


    }> = NativeModules.RNModuleTemplate;


    export function getTimeZone(): Promise {


    return NativeModule.getTimeZone();


    }


    Objective-C TypeScript

    View full-size slide

  12. @ReactMethod


    public void getTimeZone(Promise promise) {


    try {


    promise.resolve(TimeZone.getDefault().getID());


    } catch (Exception exception) {


    promise.reject("error_code",


    exception.getMessage());


    }


    }
    Java
    import { NativeModules } from "react-native";


    const NativeModule: Readonly<{


    getTimeZone: ()
    =
    > Promise;


    }> = NativeModules.RNModuleTemplate;


    export function getTimeZone(): Promise {


    return NativeModule.getTimeZone();


    }


    TypeScript

    View full-size slide

  13. What's the bridge for?
    Reading sync data using constants,


    Calling async methods using promises or callbacks,


    Receiving events using event listeners

    View full-size slide

  14. - (void)startObserving {


    [[NSNotificationCenter defaultCenter]


    addObserver:self


    selector:@selector(onTimeZoneChange)


    name:NSSystemTimeZoneDidChangeNotification


    object:nil];


    }


    - (void)stopObserving {


    [[NSNotificationCenter defaultCenter]


    removeObserver:self


    name:NSSystemTimeZoneDidChangeNotification


    object:nil];


    }


    - (NSArray*
    > *)supportedEvents {


    return @[@"timeZoneChange"];


    }


    - (void)onTimeZoneChange {


    [self sendEventWithName:@"timeZoneChange" body:@{


    @"date": [[NSISO8601DateFormatter new] stringFromDate:[NSDate date]],


    @"value": [[NSTimeZone localTimeZone] name],


    }];


    }


    Objective-C
    import { NativeEventEmitter, NativeModules } from "react-native";


    const emitter = new NativeEventEmitter(NativeModules.RNModuleTemplate);


    type Listeners = {


    timeZoneChange: (body: { date: string; value: string })
    =
    > void;


    };


    export function addListener(


    type: Type,


    listener: Listeners[Type],


    ): ()
    =
    > void {


    const subscription = emitter.addListener(type, listener);


    return subscription.remove;


    }


    TypeScript

    View full-size slide

  15. WritableMap body = Arguments.createMap();


    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",


    Locale.getDefault());


    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));


    body.putString("date", dateFormat.format(new Date()));


    body.putString("value", TimeZone.getDefault().getID());


    getReactApplicationContext()


    .getJSModule(RCTDeviceEventEmitter.class)


    .emit("timeZoneChange", body);


    import { NativeEventEmitter, NativeModules } from "react-native";


    const emitter = new NativeEventEmitter(NativeModules.RNModuleTemplate);


    type Listeners = {


    timeZoneChange: (body: { date: string; value: string })
    =
    > void;


    };


    export function addListener(


    type: Type,


    listener: Listeners[Type],


    ): ()
    =
    > void {


    const subscription = emitter.addListener(type, listener);


    return subscription.remove;


    }


    Java TypeScript

    View full-size slide

  16. How to organize your
    module repository

    View full-size slide

  17. Sources
    github.com/zoontek/react-native-module-template


    - or -


    github.com/callstack/react-native-builder-bob

    View full-size slide

  18. That was the


    first 20%


    of the work

    View full-size slide

  19. (
    This one is a joke)
    (
    It still triggered me)

    View full-size slide

  20. Huge projects depend on


    single-maintainer dependencies

    View full-size slide

  21. Preserve yourself

    View full-size slide

  22. My tricks to avoid


    open-source burnout 😌

    View full-size slide

  23. How it was done before github issue forms

    View full-size slide

  24. Don't feel bad for not dealing with
    everything

    View full-size slide

  25. A friend 👉
    Also a friend 👉
    Also a friend 👉

    View full-size slide

  26. Don't do it for money 💸

    View full-size slide

  27. Know what you want to maintain


    Why not a PHILOSOPHY
    (
    .md)?
    You think it belongs to module core
    You think it doesn't
    Consider the PR
    Feel free to refuse


    (and explain nicely why)

    View full-size slide

  28. Know what you want to maintain


    Especially in the React Native environment

    View full-size slide

  29. Think about:


    React Native updates and breaking changes


    iOS updates and breaking changes


    Android updates and breaking changes


    macOS updates and breaking changes


    Windows updates and breaking changes


    RNW updates and breaking changes


    React updates and breaking changes



    View full-size slide

  30. Focus on one thing


    Let people create their own abstractions in user-land

    View full-size slide

  31. Embrace help 🤝


    Even if they don't know the tech,


    people can help you (triage, linking to similar issues,
    asking for more details, etc.)

    View full-size slide

  32. 🙇 Thank you! Questions?
    Mathieu Acthernoene


    Lead front-end developer
    @
    Swan


    Podcast host
    @
    Putain de Code !

    View full-size slide

  33. Sources:


    - https://formidable.com/blog/2019/react-codegen-part-1


    - https://mikemcquaid.com/2018/03/19/open-source-maintainers-owe-you-nothing/


    - https://github.com/facebook/react-native/issues/23313


    - https://github.com/doczjs/docz/issues/1634

    View full-size slide