JSONX Manual
- Home
- Getting Started
- Using Advanced Props
- External and Custom Components
- Creating React Components and Component Libraries
- JSONX & JXM Spec
- Samples
- Roadmap
- Full API Docs
Creating new components
“With great power comes great responsibility”. Just because you can create new Class and Function components with JSONX it doesn’t mean you should. Typically, components should be bundled as UMDs and imported as Custom/External components to optimize performance.
- 1. Class Components - Use
jsonx._jsonxComponents.getReactClassComponent
and JXM to create React Class Components with JSON - 2. Function Components - Use
jsonx._jsonxComponents.getReactFunctionComponent
and JXM to create React Function Components with JSON. Because JSONX can uses React under the hood, all React features are available (e.g. Hooks, Lazy and Suspense). - 3. Dynamic Components - Use
jsonx._jsonxComponents.DynamicComponent
is a special component that renders components after fetching data.
1. Class Components
JSONX exposes the jsonx._jsonxComponents.getReactClassComponent
function that can you can use to create React Class Components. getReactClassComponent
uses createReactClass
underneath the hood. You can read more about using createReactClass
in the React docs section about “React Without ES6”.
export function getReactClassComponent(
reactComponent = {},
options = {},
): ReactComponentLike
getReactClassComponent
takes two arguments reactComponent
which contains the arguments passed to createReactClass
and an options
argument.
The only required function in the reactComponent
parameter object is a render function, the body of the function has to be valid JXM JSON. Each property in the object has two properties a body
property whose value is the function body and an arguments
property which defines the parameters for the function.
const reactComponent = {
//
// Initialization function
//
getInitialState:{
body:'return { status:"not-loaded", name:"jsonx test", customNumber:1, }',
arguments:[],
},
getDefaultProps:{
body:'return { someProp:1, someOtherProp:2, status:"original status" }',
arguments:[],
},
componentDidMount:{
body:`console.log('mounted', 'this.props',this.props, 'this.state',this.state)`,
arguments:[],
},
componentWillUnmount:{
body:`console.log('unmounted',this.props)`,
arguments:[],
},
//
// State change functions
//
shouldComponentUpdate:{
body:'console.log("should update component",{nextProps,nextState}); return true;',
arguments:['nextProps', 'nextState']
},
componentWillUpdate:{
body:'console.log("will update component",{nextProps,nextState}); return true;',
arguments:['nextProps', 'nextState']
},
componentDidUpdate:{
body:'console.log("did update component",{prevProps,prevState}); return true;',
arguments:['prevProps', 'prevState']
},
//
// Prop change functions
//
componentWillReceiveProps: {
body:'console.log("will recieve props",{nextProps}); return true;',
arguments:['nextProps']
},
//
// RENDER IS THE ONLY ***REQUIRED*** FUNCTION
//
render:{
body:{
component:'p',
props:{
status:'from inline prop'
},
passprops:true,
children:[
{
component:'span',
children: 'My Custom React Component Status: ',
},
{
component:'span',
thisprops:{
children:['status']
}
}
]
},
}
};
const options = {
name:'MyCustomComponent',
};
const MyCustomComponent = jsonx._jsonxComponents.getReactClassComponent(reactComponent,options);
const JXM = {
component:'MyCustomComponent',
props:{
status:'Amazing',
}
};
const boundConfig = {
debug:true,
reactComponents:{
MyCustomComponent,
}
};
jsonx.jsonxRender.call(boundConfig, {
jsonx: JXM,
querySelector:'#main', });
Console output after mounting
[Log] mounted (4)
"this.props"
{status: "Amazing", children: {}, someProp: 1, someOtherProp: 2}
"this.state"
{status: "not-loaded", name: "jsonx test", customNumber: 1}
Example Class Components
2. Function Components
JSONX exposes the jsonx._jsonxComponents.getReactFunctionComponent
function that can you can use to create React Function Components.
export function getReactFunctionComponent(
reactComponent: JXM_JSON,
functionBody: string,
options = {},
): ReactComponentLike
getReactFunctionComponent
takes three arguments:
reactComponent
which contains the JXM JSON for rendering the Function Component.functionBody
which is a string for the Function component (if you are using hooks or want to expose props from inside of your components, assign the props you want to make available to anexposeprops
variable)options
used to customizegetReactFunctionComponent
.
const hookFunctionComponent = jsonx._jsonxComponents.getReactFunctionComponent(
//reactComponent
{
component:'div',
passprops:true,
children:[
{
component:'button',
__dangerouslyBindEvalProps:{
onClick:function(clicks,set_click){
set_click(clicks+1);
},
},
thisprops:{
clicks:['clicks'],
set_click:['set_click']
},
children:'Click Me',
},
{
component:'span',
children:' Clicks: '
},
{
component:'span',
thisprops:{
_children:['clicks'],
}
}
]
},
//functionBody
`
const [clicks, set_click] = useState(0);
const exposeprops = {clicks,set_click};
`,
//options
{
name:'hookFunctionComponent',
});
Example Function Components
3. Dynamic Components
JSONX has a helper component called DynamicComponent
. Using DynamicComponent
allows you to create components that load data and render asynchronously.
The typical use case is if you have some kind of dashboard or components that are independently loading data, Dynamic Components are a convenient way to handle dynamic components without Suspense and Lazy Components (they use hooks under the hood).
Once the data is fetched, the jsonx
object passed is rendered and the resolved data is available as resourceprops.DynamicComponentData
.
const JXM = {
component: 'DynamicComponent',
props: {
useCache: boolean;
cacheTimeout: number;//milliseconds
loadingJSONX: jsonx;
loadingErrorJSONX: jsonx;
cacheTimeoutFunction: () => void,
jsonx: jsonx;
transformFunction: (data: any) => any,
fetchURL: string;
fetchOptions: any;
fetchFunction: (fetchURL: string, fetchOptions: any)=>Promise,
}
};
const dynamicComponent = jsonx.getReactElementFromJSONX({
{
component:'DynamicComponent',
props:{
fetchURL:'/path/to/some/data'
jsonx:{
component:'p',
children:'loaded data',
}
}
},
});