@omneo/shapes-react-helpers v0.0.7
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
Shapehelper component to easily hydrate and filter Shape resourceswithShapescomponent wrapper for simple context subscription- Automatic shape rendering using
data-omneo-shapeattribute
Getting started
$ yarn add @omneo/react-shapes-providerInclude 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 ProfileNamewithShapes()
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 AppIncluding 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 AppAdvanced 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.