npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@d11/react-native-remote-ui

v0.1.0

Published

Remote component for react native

Downloads

20

Readme

react-native-remote-ui

Remote Component allow react-native (Host) applications to render remote (Server) components. Remote components are loaded through URI at runtime. Remotely loaded components behaves similar to the locally imported components.

Remote Component are babel transpiled source code of tsx or jsx, which is executed at runtime. This gives capability to update/change UI without app release. Remote Components can use hooks like useState and also react lifecycle events like useEffect.

Installation

npm install react-native-remote-ui

Usage

Remote Component

// Host Application Component using RemoteComponent

import * as React from 'react';
import { View } from 'react-native';
import { RemoteComponent } from 'react-native-remote-ui';

const FallbackComponent = () => {
  return (
    <View>
      <Text> Fallback Component </Text>
    </View>
  );
};

export default function App() {
  return (
    <View style={{ flex: 1 }}>
      <RemoteComponent
        source={{ uri: 'https://api.server.com/promotion-card.jsx' }}
        fallbackComponent={<FallbackComponent />}
      />
    </View>
  );
}
// Remote Component hosted on server

export const HomeComponent = () => {
  return (
    <View>
      <Text> Remote Component </Text>
    </View>
  );
};

Pre Load Component

import * as React from 'react';
import { View } from 'react-native';
import {
  RemoteComponent,
  preloadRemoteComponent,
} from 'react-native-remote-ui';

export default function App() {
  // make sure to preload before actual usage
  // components are cached againt URI

  const preloadComponent = async () => {
    try {
      const { preload } = preloadRemoteComponent({});
      await preload('https://api.server.com/player-card.jsx');
    } catch (e) {
      console.error('Failed to preload. ', e);
    }
  };

  React.useEffect(() => {
    preloadComponent();
  }, []);

  return (
    <View style={{ flex: 1 }}>
      <RemoteComponent
        source={{ uri: 'https://api.server.com/player-card.jsx' }}
        fallbackComponent={<FallbackComponent />}
      />
    </View>
  );
}

How does it work?

Alt text

Remote Component requires transpiled *.tsx (jsx) code to be executed at runtime in host application. Babel is used to transpile the .tsx or .jsx file in format Remote Component can understand.

Babel command to transpile tsx or jsx

npx babel --presets=@babel/preset-env,@babel/preset-react ExampleRemoteComponent.tsx -o TranspiledExample.js

Transpiled source code must be served from URL to Remote Component. Since remote component executes transpiled source code at runtime, right now only vanilla react native components can be used in Remote Component. For any third party library usage, import must be resolved at runtime. Resolving imports for third party dependencies can be done by providing global prop. For successful import resolution at runtime, the third party dependency must be part of original bundle shipped with host application.

// Remote Component hosted on server

import * as React from 'react';
// Buttton component used from react-native-elements
import { Button } from '@rneui/base';
import { View } from 'react-native';

const RemoteComponent = () => {
  return (
    <View>
      <Button title="Hello World!" />;
    </View>
  );
};

To resolve import of Button at runtime in host application, global prop must be provided to Remote Component

// Host application component using remote component

const App = () => {
  return (
    <View>
      <RemoteComponent
        global={{
          require: (moduleId: string) => {
            if (moduleId === '@rneui/base') {
              return '@rneui/base';
            }
            return null;
          },
        }}
      />
    </View>
  );
};

Props

  • source
    • URI to fetch component source
  • fallbackComponent
    • Fallback component provided to React Suspense
  • errorComponent
    • Component to be used in case of error in RemoteComponent
  • loadingComponent
  • onAction
    • Callback with action and payload. Current supported actions are NAVIGATE, IO.
  • global
    • Custom import resolution, used by Remote Component at runtime

Handling Actions on Remote Component

Remote Component is capable of handling all the user interactions. They can emit event to let host application know about actions, host application needs to implement onAction callback provided by Remote Component. onAction callback has two parameters action type and payload

// Host application

const handleAction = useCallback(
  (action: string, payload: Record<string, any>) => {
    switch (action) {
      case 'NAVIGATE':
        navigation.navigate(payload.route);
        break;
    }
  },
  [navigation]
);

<RemoteComponent
  source={{ uri: 'https://api.server.com/card.jsx' }}
  fallbackComponent={<FallbackComponent />}
  onAction={handleAction}
/>;

Action emitted contains action type and payload.

// Example Remote Component

const ExampleRemoteComponent = ({
  onAction,
}: {
  onAction: (action: any, payload: Record<string, any>) => void;
}) => {
  const onPress = useCallback(() => {
    if (onAction) {
      onAction('NAVIGATE', { route: 'DetailsScreen' });
    }
  }, [onAction]);

  return (
    <View>
      <Pressable onPress={onPress}>
        <View>
          <Text> {`Navigation`} </Text>
        </View>
      </Pressable>
    </View>
  );
};

Component Caching

Remote Components are cached in-memory for URI. Internally axios is used to fetch source from URI. Cache-Control header in response is used to burst cache session. Cache-Control should follow standard format e.g. max-age=$value where value is in milliseconds.

Running example app

Example has server folder which contains express server and mocks for Remote Component.

cd example

# transpile component
yarn transpile:mock

# start server
# This will start serving transpiled mock
yarn start:server

# start metro
yarn start

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT


Made with create-react-native-library