vadim.blog | Vadim Nicolai

Code Sharing Between React Web And React Native

November 21st, 2018

One of the advantages of using React Native is the possibility of sharing code across different devices. This is achievable because under the hood React Native is using the same component which is used on the web.

alt text

The difference is only in platform specific UI components. This is why we will reuse the logic of the app. For applying styles I will use styled components which has React Native implementation which will be useful in reusing styles across different platforms.

The starting point is root component which is the same for all platforms:

jsx
import React, { Fragment } from 'react';
import ListUsers from './containers/ListUsers';
import CreateUser from './containers/CreateUser';
const App = () => (
<Fragment>
<ListUsers />
<CreateUser />
</Fragment>
);
export default App;

This component includes 2 containers in which resides our shared logic:

ListUsers :

jsx
import React, { Component } from 'react';
import API from '../services/api';
import List from '../components/List';
export default class ListUsers extends Component {
state = {
persons: [],
};
componentDidMount() {
API.get('users').then(({ data: persons }) => this.setState({ persons }));
}
render() {
const { persons } = this.state;
return <List data={persons} />;
}
}

CreateUser :

jsx
import React, { Component, Fragment } from 'react';
import { pathOr } from 'ramda';
import API from '../services/api';
import Input from '../components/Input';
import Button from '../components/Button';
export default class CreateUser extends Component {
state = {
name: '',
};
handleChange = (event) => {
const name = pathOr(event, ['target', 'value'])(event);
this.setState({ name });
};
handleSubmit = () => {
const { name: user } = this.state;
API.post('users', { user }).then((res) => console.log(res.data));
};
render() {
const { name } = this.state;
return (
<Fragment>
<Input value={name} handleChange={this.handleChange} />
<Button onAction={this.handleSubmit} title="Create user" />
</Fragment>
);
}
}

All the magic is happening when we are importing components:

js
import List from '../components/List';

List is a folder with different extensions .js, .ios.js and .android.js. Depending on which platform we want to execute our app, corresponding file will be loaded. .js will be loaded for the web version, the rest will be loaded according to platform extension, more details here.

And, lastly we will reuse styles, by creating a common styles file:

js
import { css } from 'styled-components';
const styles = css`
background-color: red;
`;
export default styles;

Then we will wrap platform specific element/ component.

For web:

jsx
import React from 'react';
import styled from 'styled-components';
import styles from './styles';
const Button = styled.button`
${styles}
`;
const ButtonItem = ({ title, onAction }) => (
<Button onClick={onAction}>{title}</Button>
);
export default ButtonItem;

And for mobile:

jsx
import React from 'react';
import { Button } from 'react-native';
import styled from 'styled-components/native';
import styles from './styles';
const StyledView = styled.View`
${styles}
`;
const ButtonItem = ({ onAction, title = 'Button' }) => (
<StyledView>
<Button onPress={onAction} title={title} accessibilityLabel={title} />
</StyledView>
);
export default ButtonItem;

Here is the repo with all code.

More Articles

CRUD App Using GraphQL Apollo Server, MongoDB And Angular

Until GraphQL came out, RESTful API was the most popular choice for client-server communication. REST has been defined about 20 years ago…
October 31st, 2018
© 2021 vadim.blog | Vadim Nicolai