21

Is it possible to setup a project which has code for both React Native(Mobile app) + React(web), having the code shred between platforms except for the UI part.

Have done something similar with Angular + NativeScript using this seed, which enables code sharing between native app and web application(Except for the UI layer). Looking for something similar for React + React Native.

Please share if you know any such seed for React Native + Angular as well, if available.

Anand
  • 9,672
  • 4
  • 55
  • 75
  • 7
    I don't understand why people down vote without commenting what's wrong with the question. I do make my little contribution to this community and hurts when the same community does like this. Down votes are fine. But tell whats wrong with it guys!! – Anand Feb 03 '18 at 04:56
  • 2
    I am also curious about both things ... the vague downvoting doesn't really seem to help anyone, I think. – jess Feb 04 '18 at 22:08
  • _Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, [describe the problem](https://meta.stackoverflow.com/questions/254393) and what has been done so far to solve it._ – bennygenel Feb 06 '18 at 10:04
  • 8
    @bennygenel I humbly deny the claim that this question is asking on library/tutorial suggestion. Question specifically is asking for the feasibility and compatibility of one project hosting two frameworks - React and React native and possibility of code sharing in that setup (This is a well known approach with Angular + Nativescript, which is referenced as an example). In addition, it also asks for any such seed project implementation. Hope community understands and helps with this question. – Anand Feb 06 '18 at 16:29

6 Answers6

12

Jonathan Kaufman has a good article on how to set this up: http://jkaufman.io/react-web-native-codesharing/

The basic strategy is to have a different entry point (index.js) for each platform (android/ios/web). Then the majority of your non-rendering code can live in a shared app or common folder. You'll still need to segregate your rendering code (i.e. uses of View, div, etc.), though, as that will differ by platform.

Pay attention to the comments on that article as well, as there's some good discussion on the pitfalls of this approach. Example:

By sharing a common package.json between native and web, you've glued them together by their common dependencies, the most important one being react. Let's say you upgrade to a version of react-native that depends on >= react@16, but your web app depends on some other library which depends on =< react@15. --timtas

Luke Willis
  • 8,429
  • 4
  • 46
  • 79
5

You can give a try to React-Native-Web, but imho you should create 2 different projects, isolate and copy what can be used on both (like api requests and util functions). Your code will be easier to debug and maintain.

Dyo
  • 4,429
  • 1
  • 15
  • 30
  • 5
    Copying code that can be reused is quite the opposite of what the author of the questions is trying to achieve... And: Its bad practice. Having code that does the same twice in a project is never a good idea... – four-eyes Jul 19 '18 at 14:31
3

Yes, absolutely possible. We've done it before using this lib react-native-web. https://github.com/necolas/react-native-web

beside index.ios.js and index.android.js, you will need create index.web.js, the content should be similar like this.

import { AppRegistry } from 'react-native';
import App from './app/Containers/App/App.container';

AppRegistry.registerComponent('ReactNativeWeb', () => App);
AppRegistry.runApplication('ReactNativeWeb', { rootTag: document.getElementById('react-app') });

also you need to create your own nodejs code to serve up the bundle. full reference

I Putu Yoga Permana
  • 3,980
  • 29
  • 33
3

I do it this way.

1) Create a React Native project.
2) Add react-dom and react-scripts dependencies to package.json and install them.
3) All the component code is separated this way:

My regular React Native component:

// MyComponent.js
class MyComponent extends React.Component {
    costructor(props) {
        ...
    }
    someMethod() {
        ...
    }
    render() {
        return (
            <View>
                ...
            </View>
        )
    }
}

Changed for using in web:

// MyComponentController.js
class MyComponentController extends React.Component {
    costructor(props) {
        ...
    }
    someMethod() {
        ...
    }
}

// MyComponent.js
const MyComponentController = require('./MyComponentController')
class MyComponent extends MyComponentController {
    render() {
        return (
            <div>
                ...
            </div>
        )
    }
}

// MyComponent.native.js
const MyComponentController = require('./MyComponentController')
class MyComponent extends MyComponentController {
    render() {
        return (
            <View>
                ...
            </View>
        )
    }
}

And then I use in it in all the platforms:

const MyComponent = require('./MyComponent')

For this to work nicely with an old project I had to implement some dummies, but it all can be done better by your own layer of abstraction. Part of my example:

const ReactNative = {
    Platform: {
        OS: 'web'
    },
    AppRegistry: {
        registerComponent: (name, provider) => {
            const Component = provider()
            ReactDOM.render(
              <Component />,
              document.getElementById('root')
            );
        }
    },
    AsyncStorage: {
        setItem: (key, value, callback) => {
            localStorage.setItem(key, value)
            callback()
        },
        getItem: key => {
            const val = localStorage.getItem(key) || null
            return new Promise(ok => ok(val))
        }
    },
    StyleSheet: {
        create: dict => dict
    },
    Dimensions: {
        get: function() {
            // http://stackoverflow.com/questions/3437786/get-the-size-of-the-screen-current-web-page-and-browser-window
            const w = window
            const d = document
            const e = d.documentElement
            const g = d.getElementsByTagName('body')[0]
            const x = w.innerWidth || e.clientWidth || g.clientWidth
            const y = w.innerHeight|| e.clientHeight|| g.clientHeight
            return {
                width: x,
                height: y
            }
        }
    },
    Linking: {
        openURL: (url) => {
            window.open(url)
        }
    },
    // etc, I add dummies as soon as I need them
}

But, as I said, this was necessary only because I did not have much time and had not known in advance that I would have to port to web.

Serge Seredenko
  • 3,541
  • 7
  • 21
  • 38
1

You can try the repo that I tried to prepare:

https://mehmetkaplan.github.io/react-spa-jwt-authentication-boilerplate/

This has a step by step guideline that enables to share common logic between react and react-native applications.

It aims to differentiate only in the presentation layer. Other than that all logic is compiled to be shared between applications.

It also comes with facebook and google logins, database (mysql) integration, WebView task generation, etc.

And also it gives the fundamental know-how on "single page applications", "JWT (json web token) based security", etc..

Once read the README, you can simply clone the repo and set your environment (Database) and start developing business logic on top of the shared code structure and security baseline.

Mehmet Kaplan
  • 1,723
  • 2
  • 20
  • 43
-3

You can create 3 stand-alone applications - React, React-native & Server. Both React & React-native will use the same services from your back-end app. Else go with a single app where on loading home page, app will understand the device and render React / React-native code as per the device.

  • Its not about choosing react / react native in runtime (which is not possible anyways, as we will already be having a react native app deployed to mobile devices and on opening, its already react native). Question is about how to have one code base, sharing possible shared logic and build for different platform. Thanks for the response :) – Anand Feb 13 '18 at 14:48