SHARING CODE BETWEEN REACT AND RECT-NATIVE
GOOD, BAD &UNSHARABLE
bene@theodo.co.uk
Ben Ellerby
First React-Native London Meetup July 28, 2016
Types of Code
UI Render
Business Logic
Configuration
ui rENDER coDE
UI Render
- Different render environments (<div> != <View>)
- React-Native-Web (no longer supported by Twitter and SSR issues)
- ReactXP (SSR issues and have not seen a project using it successfully)
- styled-components/universal (Same SSR issues as React-Native-Web and too experimental)
Styled-components
UI Render
Visual primitives for the component age.
const Button = styled.button`
border-radius: 3px;
padding: 0.25em 1em;
margin: 0 1em;
background: transparent;
color: palevioletred;
border: 2px solid palevioletred;
`;
Really helpful in React, but not always chosen for React-Native project
(I'm a fan, even if tagged template literals get some getting used to)
Styled-components
/universal
UI Render
Styled-components
/universal
UI Render
Builds off React-Primitives
"
- Animated
- StyleSheet
- View.
- Text
- Image
- Touchable
- Easing
- Dimensions
- PixelRatio
- Platform:(iOS, Android, Web, Sketch, VR,...)
TextInput
https://github.com/lelandrichardson/react-primitives
Styled-components
/universal
UI Render
Styled-components
/universal
UI Render
Sketch
React
React-Native
Styled-components
/universal
UI Render
Note that this is an experimental release: There might be bugs and there also isn’t a massive amount of documentation
ui rENDER coDE
UI Render
I believe that Web, Mobile Web and Native Application environments all require a specific design and user experience.
Types of Code
UI Render
Business Logic
Configuration
API / Formatting
Types of Code
API / Formatting
API calls, authentication and formatting of request & response data.
Types of Code
Configuration
Config files, translation files and most constant data is not render environment specific.
If I update a translation on my app, it's likely I want that changed rolled out on my site too.
Types of Code
Business Logic
Again environment independent.
If a user can only add 20 items to their basket, this rule will hold true in web and native equally.
Types of Code
UI Render
Business Logic
Configuration
API / Formatting
State Management & Data
+
State Management & Data
+
- modal open
- translations
- analytic event firing...
- product data
- search
- pagination...
State Management & Data
UI
Render Environment Independent
Our whole redux store is shared
Our Apollo queries are shared
Higher Order Components
A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature.
Higher Order Components: Apollo
// @flow
import React from 'react';
import { Query } from 'react-apollo';
const withData = (query, backupData) => WrappedComponent => {
return props => (
<Query query={query} pollInterval={10000}>
{injectedProps => <WrappedComponent backupData={backupData} {...injectedProps} {...props} />};
</Query>
);
};
export default withData;
Higher Order Components: Apollo
All Apollo query HOCs are shared:
e.g. withSearchResults, withBasket, withProducts
APPROACH To Sharing
MadeNative
MadeWeb
MadeShared
APPROACH To Sharing
MadeShared
/hoc
/queries
/conditional-render...
/dataFormatting
/config
/translations /colours
/types /api
/redux
/actions
/reducers
/selectors
APPROACH To Sharing
import React from 'react';
import { connect } from 'react-redux';
import { compose, branch, renderComponent } from 'recompose';
import { getUserPermissionSets } from 'redux/login/login.selectors';
const mapStateToProps = state => ({
userPermissions: getUserPermissionSets(state),
});
export default (permission, UnauthorisedComponent) =>
compose(
connect(mapStateToProps),
branch(
({ userPermissions }) => !userPermissions.includes(permission),
renderComponent(UnauthorisedComponent),
),
);
renderIfAuthorised(permissionsMap.CREATE_ROLE)(
RoleCreationPageWrapper,
);
APPROACH To Sharing
MadeShared
var path = require('path');
module.exports = {
entry: './shared/index.js',
output: {
path: path.resolve(__dirname),
filename: 'index.js',
libraryTarget: 'commonjs2',
},
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'shared'),
exclude: /(node_modules|bower_components|build)\//,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
},
},
},
],
},
externals: {
react: 'commonjs react',
'react-apollo': 'commonjs react-apollo',
},
};
Webpack config to transpile to commonjs2
APPROACH To Sharing
...
"dependencies": {
...
"made-shared":
"git+https://AUTHTOKEN:x-oauth-basic@github.com/REPO/made-shared.git#master-1.05",
...
...
MadeWeb / MadeNative
- Using basic x-auth tokens of a 'bot' user with read-only access
- Using git tags as versions (#BRANCH-VERSION)
- `yarn link` for local dev
APPROACH To Sharing
...
"dependencies": {
...
"made-shared":
"git+https://AUTHTOKEN:x-oauth-basic@github.com/REPO/made-shared.git#master-1.05",
...
...
MadeWeb / MadeNative
yarn build
git tag master-1.06
git push --tags
git merge
Update package.json
APPROACH To Sharing
MadeWeb / MadeNative
...
"dependencies": {
...
"made-shared": "1.05",
...
...
App Center!
MadeNative
We use AppCenter as our App CI
It needs to pull the shared library, but it's private...
App Center!
MadeNative
Me: Hello, we’re wanting to have a shared library used in our project. This would require an npm install from a private NPM repo (through package cloud). What is the best practice for adding a private npm access on the AppCenter CI?
App Center!
MadeNative
Microsoft: We currently only support cloud git repositories hosted on VSTS, Bitbucket and GitHub. Support for private repos is not available yet but we are building new features all the time, you can keep an eye out on our roadmap for upcoming features.
App Center!
MadeNative
Conclusion
- Code sharing is a great advantage of React & React-Native
- Share your non-design render code.
- Your app and web app should have a different UX
- HOCs help share component logic
- Publishing a private npm package creates a good workflow
Thanks, MADE.COM
bene@theodo.co.uk
ben@ellerby.tech
https://www.linkedin.com/in/benjaminellerby/
Sharing Code Between React and React-Native: The Good, The Bad and the Unsharable
By Ben Ellerby
Sharing Code Between React and React-Native: The Good, The Bad and the Unsharable
Talk given at the React-Native-London meetup.
- 815