React Native integration (experimental)
Follow these steps to use Flareact with React Native and React Native Web.
First, run react-native init YourAppName
. Move the following files and folders from the created YourAppName
folder to your Flareact project root:
android
ios
app.json
babel.config.js
flareact.config.js
App.js
index.js
- rename toindex.native.js
metro.config.js
Add React Native to your project:
yarn add react-native react-native-web
yarn add -D babel-plugin-react-native-web
Then, in your project root directory create flareact.config.js
with the following content:
module.exports = {
webpack: (config, { dev, isWorker, defaultLoaders, webpack }) => {
const babelConfig = config.module.rules[0].use.options;
babelConfig.plugins = [['react-native-web', { commonjs: true }]];
// Taken from https://github.com/vercel/next.js/blob/86160a5190c50ea315c7ba91d77dfb51c42bc65f/examples/with-react-native-web/next.config.js
config.resolve.alias = {
...(config.resolve.alias || {}),
// Transform all direct `react-native` imports to `react-native-web`
'react-native$': 'react-native-web',
};
config.resolve.extensions = [
'.web.js',
'.web.ts',
'.web.tsx',
...config.resolve.extensions,
];
return config;
},
};
In the pages
directory create _document.js
with the following content:
import Document, { Html, Head, Main, FlareactScript } from 'flareact/document';
import React from 'react';
import { AppRegistry } from 'react-native';
import config from '../app.json';
// Taken from https://github.com/vercel/next.js/blob/3c992063135f553b507dd49d28d2b19aebed3ac6/examples/with-react-native-web/pages/_document.js
const normalizeFlareactElements = `
#__flareact {
display: flex;
flex-direction: column;
height: 100%;
}
`;
class ReactNativeWebDocument extends Document {
static async getEdgeProps(ctx) {
// Based on https://github.com/vercel/next.js/blob/3c992063135f553b507dd49d28d2b19aebed3ac6/examples/with-react-native-web/pages/_document.js
// and https://github.com/flareact/flareact/blob/148db4fe79f65b111ea495eae9c647a247cfd113/examples/with-styled-components/pages/_document.js
AppRegistry.registerComponent(config.name, () => Main);
const initialProps = await Document.getEdgeProps(ctx);
const { getStyleElement } = AppRegistry.getApplication(config.name);
return {
...initialProps,
styles: (
<>
<style dangerouslySetInnerHTML={{ __html: normalizeFlareactElements }} />
{initialProps.styles}
{getStyleElement()}
</>
),
};
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<FlareactScript />
</body>
</Html>
);
}
}
export default ReactNativeWebDocument;
Now your application has two entrypoints: index.native.js
for the mobile app, and the original index.js
(which you can now optionally rename to index.web.js
) for the browser. You will probably want to use a separate library like react-navigation
for your mobile app navigation, and place shared components in a separate shared
folder.