React is known to be a multi-platform UI library, but it is not that simple to get done. There are many renderers (as: react-dom, react-native, react-primitives, reactxp, react-blessed, react-tv, react-pdf, redocx, react-360, etc) which allow components to run in different platforms. When you write a component that dependends directly on a component specific to some platform, this means it wont run on any other platform.
react-agnostic
makes it so you can write your components without any direct dependencies from platform specific components. It applies inversion of control using react context pass around components.
This module is distributed via npm which is bundled with node and
should be installed as one of your project's dependencies
:
npm install --save react-agnostic
This library exports a component and a HOC (Higher Order Component)
This component allows the components augmented by withComponents
to access platform specific components.
At the top level of your app, setup specific platform components and render the ComponentsProvider
component passing a components
prop.
If you're using create-react-app, your App.js file would look something like this:
import React from 'react'
import {ComponentsProvider} from 'react-agnostic'
import UpdateCartItem from './components/UpdateCartItem'
const Text = props => (
<span
{...props}
style={{fontFamily: 'monospace', padding: 10, fontSize: 24}}
/>
)
const View = props => (
<div
{...props}
style={{backgroundColor: '#222', padding: 20, color: 'white'}}
/>
)
const Button = props => (
<button
{...props}
style={{
border: '1px solid orange',
display: 'inline',
backgroundColor: 'gray',
color: 'white',
width: 30,
height: 30,
borderRadius: 15,
}}
/>
)
const components = {
View,
Text,
Button,
}
class App extends React.Component {
state = {
item: {
name: 'ball',
amount: 3,
},
}
render() {
return (
<ComponentsProvider components={components}>
<UpdateCartItem
item={this.state.item}
updateCartItem={item => this.setState({item})}
/>
</ComponentsProvider>
)
}
}
export default App
This HOC injects a components
that you to access specific platform components.
Example usage:
import React from 'react'
import {withComponents} from 'react-agnostic'
const UpdateCartItem = ({item, updateCartItem, components}) => {
const {Button, Text, View} = components
return updateCartItem ? (
<View>
<Button
disabled={item.amount <= 0}
onClick={() => updateCartItem({...item, amount: item.amount - 1})}
>
-
</Button>
<Text>{item.amount}</Text>
<Button
onClick={() => updateCartItem({...item, amount: item.amount + 1})}
>
+
</Button>
</View>
) : (
<Text>{item.amount}</Text>
)
}
export default withComponents(UpdateCartItem)
Begin by cloning this repository, then cd into it.
git clone https://github.com/vicentedealencar/react-agnostic
cd react-agnostic
cd examples/cra
npm install
npm start
npm install -g expo-cli
cd examples/crna
npm install
expo start
cd examples/proton
npm install
npm start
cd examples/reactxp
npm install
# web
npm web-watch
start index.html
# native
npm start
npm run android
npm run ios
Repository based on kcd-oss
Blog with many react supported renderers: https://dev.to/kayis/react-can-do-it-31di
- react-native
- react-native-windows
- react-primitives
- reactxp
- proton-native
- react-blessed
- react-pdf
- redocx
- react-360
I'm not aware of any, if you are please make a pull request and add it here!
Thanks goes to these people (emoji key):
Vicente de Alencar π» π π |
---|
This project follows the all-contributors specification. Contributions of any kind welcome!
MIT