@omneo/shapes-react-helpers
v0.0.7
Published
The best way to use Omneo Shapes in any React project
Downloads
5
Maintainers
Readme
Shapes Provider for React
The best way to use Omneo Shapes in any React project
Features
- Create and consume Shape SDK clients
- Receive Shape client stat updaes through props
- Uses React Context API under the hood and exposes context for full flexibility
Shape
helper component to easily hydrate and filter Shape resourceswithShapes
component wrapper for simple context subscription- Automatic shape rendering using
data-omneo-shape
attribute
Getting started
$ yarn add @omneo/react-shapes-provider
Include the Shapes provider at the top level of your project
import {ShapesProvider} from '@omneo/shapes-react-helpers';
return(
<ShapesProvider shapesClient={{
url:"https://api.[tenant].getomneo.com/id",
token: "..."
}}/>
)
The ShapesProvider consumes a Shapes SDK client and mirrors the client state within React. This provider can then be subscribed to using React’s Context API, for components to receive the data state, as well as convenient access to all client functions (hydrate
,find
,get
…)
ShapesProvider requires a Shapes SDK client to operate. This can be passed in as a reference to an existing client initialised in React or on the window, or the ShapesProvider can create a new client with a client config object. If no client or config is passed into the provider, the provider will attempt to find an already initialised shape at window.ShapesSDKClient
Using existing client reference
const client = new ShapesSDK.init({...})
return(
<ShapesProvider
shapesClient={{
url:"https://api.[tenant].getomneo.com/id",
token: "...",
logging: true,
isPrivate: false
}}
children={children}
/>
)
Using client config
<ShapesProvider
shapesClient={{
url:"https://api.[tenant].getomneo.com/id",
token: "...",
logging: true,
isPrivate: false
}}
children={children}
/>
Automatically try and connect to window.ShapesSDKClient
<ShapesProvider children={children}/>
Context values
The ShapesProvider context exposes all resources and methods of the ShapesSDK client, in the following structure:
{
state: {
profiles: {...},
balances: {...},
transactions: {...},
... // All other resources
},
methods: {
on(),
off(),
hydrate(),
find(),
get(),
post(),
put(),
delete(),
dispatch()
}
}
This library includes a helper component that uses the ShapesProvider context and passes the context state and methods to its children. The Shape
component also includes a helper function to automatically hydrate()
configured resources and include only those resources in the state props, send to child components.
Child components to Shape
can be included as a children function
import React from 'react';
import {Shape} from './ShapesContext';
// Hydrate and include profile in props
const ProfileName = () => (
<Shape
requires={['profile']}
children={props=>(
<p>Name: {props.profile.data.full_name}</p>
)}
/>
)
They can also be included directly as JSX. Props will be added to direct children only.
import React from 'react';
import {Shape} from './ShapesContext';
// Hydrate and include balances prop. Use find() method to pluck balance value.
const ProfileName = (parentProps) => (
<Shape
requires={['balances']}
children={props=>{
const {prefix = null, suffix = null} = parentProps;
return(
<p>Rewards: {prefix}{props.methods.find('balances.data.combined_balance_dollars')}{suffix}</p>
)
}}
/>
)
export default ProfileName
withShapes()
If you don't want to use the <Shape/>
helper component, this library includes a function similar to Redux's connect()
. Simply export your React components wrapped in withShapes()
and they will receive a shapes
prop, including the state
and methods
objects from ShapesProvider.
import React from 'react';
import {withShapes} from './ShapesContext';
class RewardBalance extends React.PureComponent{
componentDidMount(){
this.props.shapes.methods.hydrate('balances');
}
render(){
const {loading, data} = this.props.shapes.state.balances;
if(loading){
return <p>Loading....</p>
}
return <p>{data.combined_balance_dollars}</p>
}
}
export default withShapes(RewardBalance)
Automatic Shapes
ShapesProvider includes the ability to automatically render named components to any element on a page with the data-omneo-shape
attribute. This can drastically reduce the complexity and heavy lifting of rendering out components such as "like" or "wishlist" buttons on a PLP - This function also allows these components to be rendered outside of the regular React structure, so data-omneo-shape
elements can be put anywhere, not just within the children
of the Provider or the React app. Automatic Shapes uses the React Portals API under the hood.
Using automatic shapes
Add the automatic
prop to <ShapesProvider>
and include the shapeTypes
prop with an object of named react components. This example will render <p>This is an example</p>
inside the <div data-omneo-shape="ExampleShape"/>
div.
import React from 'react';
import {ShapesProvider} from './ShapesContext';
const ExampleComponent = () => (
<p>This is an example</p>
)
const App = () => (
<div className="App">
<div data-omneo-shape="ExampleShape"/>
<ShapesProvider
automatic
shapeTypes={{
ExampleShape: ExampleComponent
}}
/>
</div>
)
export default App
Including automatic shape parameters
Automatic shapes will parse all data attributes on the element and include them as props. This simplifies the configuration of shapes where minor configuration is needed. Config values are included within the props.config
object.
import React from 'react';
import {ShapesProvider} from './ShapesContext';
const Name = props => (
<p>Name: {props.config.name}</p>
)
const App = () => (
<div className="App">
<div data-omneo-shape="Name" data-name="Amy"/>
<div data-omneo-shape="Name" data-name="David"/>
<div data-omneo-shape="Name" data-name="Ashley"/>
<ShapesProvider
automatic
shapeTypes={{
Name: Name
}}
/>
</div>
)
export default App
Advanced usage
As automatic shapes rendering is managed from within the ShapesProvider, all relevant context data and props are included from your React application. You can use the Shape
component or your own Redux state and all props will be retained when rendered to the page.