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
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 (
...
)
}
}
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 (
...
)
}
}
// MyComponent.native.js
const MyComponentController = require('./MyComponentController')
class MyComponent extends MyComponentController {
render() {
return (
...
)
}
}
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(
,
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.