• Stars
    star
    253
  • Rank 160,776 (Top 4 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created about 4 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An easy way to integrate your React (or Preact/React Native Web) app into React Native app with WebView.

react-native-react-bridge

npm npm check

An easy way to integrate your React (or Preact) app into React Native app with WebView.

Why?

If you'd like to run your React web app in React Native, rewriting it for React Native or using react-native-web is preferred way in most cases. But sometimes rewriting is overkill, when you are just prototyping, or when the app includes something not available on React Native, like rich text editor with contenteditable or complicated logic with WebAssembly.

So how we run React app in React Native app as it is? It's logically possible if you run your web code in WebView using react-native-webview. However bundling React code with React Native is troublesome and implementing communication between React Native and WebView is so hard.

This library gives a bridge to make it easy. This will bundle the whole React app by some additional codes and it will be automatically re-compiled if you edit it. You rarely need to think which code you are editing for React or React Native, like isomorphic. The communication between React app and React Native app will be also simplified by this.

Features

  • Create React (or Preact) app bundle for WebView automatically in build process of React Native
    • .js, .ts, .jsx, .tsx, .mjs and .cjs will be packed into one source.
    • NOTE: Only the edits in the entry file of web will invoke rebuild because of the limitation of metro's build process.
  • Handle communication between React Native and WebView with React hook style
    • With useWebViewMessage hook, you can subscribe messages from WebView.
    • With useNativeMessage hook, you can subscribe messages from React Native.
    • emit function sends message.
  • Support bundling some assets in web side with ES6 import syntax

If you have some feature requests or improvements, please create a issue or PR.

Install

npm install react-native-react-bridge react-native-webview

# Necessary only if you render React app in WebView
npm install react-dom

# Necessary only if you render Preact app in WebView
npm install preact

Requirements

  • react >= 16.8
  • react-native >= 0.60
  • (preact >= 10.0)

Supported react-native versions

react-native-react-bridge react-native
>=0.9.0 >=0.65.0
0.0.0 - 0.8.1 <=0.64.2

Usage

1. Fix metro.config.js to use babelTransformer from this library.

React Native

module.exports = {
  transformer: {
    // This detects entry points of React app and transforms them
    // For the other files this will switch to use default `metro-react-native-babel-transformer` for transforming
    babelTransformerPath: require.resolve('react-native-react-bridge/lib/plugin'),
    ...
  },
  rnrb: {
    // Set `true` if you use Preact in web side.
    // This will alias imports from `react` and `react-dom` to `preact/compat` automatically.
    preact: true
  },
  ...
};

Expo

const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

module.exports = {
  ...config,
  transformer: {
    ...config.transformer,
    babelTransformerPath: require.resolve(
      "react-native-react-bridge/lib/plugin"
    ),
  },
};

2. Make entry file for web app.

  • If you use React in web, import modules from react and react-native-react-bridge/lib/web.
  • If you use Preact in web, import modules from preact and react-native-react-bridge/lib/web/preact.
  • If you use Preact in web but with React aliases, import modules from react and react-native-react-bridge/lib/web.
// WebApp.js

import React, { useState } from "react";
import {
  webViewRender,
  emit,
  useNativeMessage,
} from "react-native-react-bridge/lib/web";
// Importing css is supported
import "./example.css";
// Images are loaded as base64 encoded string
import image from "./foo.png";

const Root = () => {
  const [data, setData] = useState("");
  // useNativeMessage hook receives message from React Native
  useNativeMessage((message) => {
    if (message.type === "success") {
      setData(message.data);
    }
  });
  return (
    <div>
      <img src={image} />
      <div>{data}</div>
      <button
        onClick={() => {
          // emit sends message to React Native
          //   type: event name
          //   data: some data which will be serialized by JSON.stringify
          emit({ type: "hello", data: 123 });
        }}
      />
    </div>
  );
};

// This statement is detected by babelTransformer as an entry point
// All dependencies are resolved, compressed and stringified into one file
export default webViewRender(<Root />);

3. Use the entry file in your React Native app with WebView.

// App.js

import React from "react";
import WebView from "react-native-webview";
import { useWebViewMessage } from "react-native-react-bridge";
import webApp from "./WebApp";

const App = () => {
  // useWebViewMessage hook create props for WebView and handle communication
  // The argument is callback to receive message from React
  const { ref, onMessage, emit } = useWebViewMessage((message) => {
    // emit sends message to React
    //   type: event name
    //   data: some data which will be serialized by JSON.stringify
    if (message.type === "hello" && message.data === 123) {
      emit({ type: "success", data: "succeeded!" });
    }
  });

  return (
    <WebView
      // ref, source and onMessage must be passed to react-native-webview
      ref={ref}
      // Pass the source code of React app
      source={{ html: webApp }}
      onMessage={onMessage}
    />
  );
};

4. Start your React Native app!

Documentation

FAQs

My webview displays a blank page.

react-native-webview has some ways to show errors occurred in webview. This may be helpful to troubleshoot it.

https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md#onerror

Demo

This repository includes demo app.

React Native

Before running this app, please prepare environment for React Native (https://reactnative.dev/docs/environment-setup).

git clone [email protected]:inokawa/react-native-react-bridge.git
cd examples/DemoApp
yarn
yarn ios # or yarn android

Expo

git clone [email protected]:inokawa/react-native-react-bridge.git
cd examples/DemoAppExpo
yarn
expo start

Contribute

All contributions are welcome. If you find a problem, feel free to create an issue or a PR.

Making a Pull Request

  1. Clone this repo.
  2. Run npm install.
  3. Commit your fix.
  4. Make a PR and confirm all the CI checks passed.

More Repositories

1

virtua

A zero-config, fast and small (~3kB) virtual list (and grid) component for React, Vue, Solid and Svelte.
TypeScript
1,166
star
2

rich-textarea

A small customizable textarea for React to colorize, highlight, decorate texts, offer autocomplete and much more.
TypeScript
296
star
3

remark-slate-transformer

remark plugin to transform remark syntax tree (mdast) to Slate document tree, and vice versa. Made for WYSIWYG markdown editor.
TypeScript
105
star
4

react-native-wasm

A polyfill to use WebAssembly in React Native.
Kotlin
83
star
5

lang-box

πŸ’» Update a pinned gist to contain languages of your recent commits in GitHub
JavaScript
52
star
6

react-animatable

Tiny(~1kB) animation hooks for React, built on Web Animations API.
TypeScript
38
star
7

remark-docx

remark plugin to compile markdown to docx (Microsoft Word, Office Open XML).
TypeScript
33
star
8

rust-editor

An implementation of text editor with Rust/WebAssembly.
Rust
25
star
9

remark-pdf

remark plugin to compile markdown to pdf.
TypeScript
24
star
10

react-use-d3

A small React hook to use D3 in declarative way, for data visualization & flexible animation.
TypeScript
7
star
11

remark-extract-toc

remark plugin to store table of contents
JavaScript
6
star
12

react-reconciler-practice

A practice with react-reconciler.
TypeScript
4
star
13

monaco-diff

Text diff library exported from monaco-editor-core, which is core of VS Code.
TypeScript
4
star
14

dotparser-normalized

A wrapper of dotparser to parse GraphViz dot file and collect nodes / edges.
TypeScript
3
star
15

react-typescript-example

Sandbox for React and TypeScript
TypeScript
3
star
16

wasm-ts-runtime

[WIP]A toy WebAssembly runtime implementation with TypeScript.
TypeScript
2
star
17

inokawa.github.io

GitHub Pages
TypeScript
2
star
18

rust-browser

A toy browser engine implementation with Rust.
Rust
2
star
19

react-native-with-web-example

A setup of React Native with React Native Web.
Java
2
star
20

apollo-graphql-practice

JavaScript
1
star
21

node-bundler

A toy JavaScript bundler with Node.js.
JavaScript
1
star
22

react-grpc-web

[WIP] Typed React hooks for gRPC-web.
TypeScript
1
star
23

tweened

A simple, declarative and composable animation library for React.
TypeScript
1
star
24

webgl-practice

WebGL sandbox
TypeScript
1
star
25

reagram

React component to render customizable graph/diagram.
TypeScript
1
star
26

arduino-sketches

Sandbox for Arduino
C++
1
star
27

rust-wasm-example

Some examples of WebAssembly generated by Rust.
Rust
1
star
28

d3-sandbox

D3.js Practice
JavaScript
1
star
29

monaco-editor-node

Wrapper of monaco-editor to use some functionalities in Node.js.
JavaScript
1
star
30

react-native-accelerate

Java
1
star
31

babel-plugin-evaluate-modules

A babel plugin to evaluate modules at build-time.
TypeScript
1
star
32

web3d-sandbox

WebGL/WebGPU/GLSL Practice
JavaScript
1
star
33

canvas-game

A toy 2D shooting game built on pure Canvas API.
TypeScript
1
star
34

webgl-mdn-practice

JavaScript
1
star
35

webgpu-practice

WebGPU sandbox
TypeScript
1
star