React Hooks
Starting from 2.1, PageBuilder Engine began supporting React’s hooks, as well as implementing its own. Currently, as of PageBuilder Engine 2.2 there are four custom hooks:
useContent
useComponentContext
useAppContext
useFusionContext
useComponentContext
import Context, { useComponentContext } from 'fusion:context';... const componentContext = useComponentContext();...
Returns an object that contains data from the parent component’s context. You’ll be able to get the global content that is hydrated with the local edits simply by getting .globalContent
on the returned object.
This function retrieves both the global contents from the PageBuilder Engine app itself as well as the component context. Both are called using React’s useContext hook. A regular call to useComponentContext
will return the component context as if calling useContext(<Component Context>)
directly.
You can also call globalContent
from the returned object to retrieve the global content after the local edits are applied. Because multiple child components could be calling the global content, it will memoize the parent component’s context by id so it doesn’t have to re-hydrate with local edits each time.
useAppContext
import Context, { useAppContext } from 'fusion:context';... const appContext = useAppContext();...
Returns an object that contains data from the application-level context. It works similarly to useComponentContext
, where the you can get the local edit-hydrated global content by getting .globalContent
on the returned object.
useFusionContext
import Context, { useFusionContext } from 'fusion:context';... const fusionContext = useFusionContext();...
Returns an object containing data from both useComponentContext
and useAppContext
. It is just a convenience method that merges the two functions and returns the combined object.
useContent
import Content, { useContent } from 'fusion:content';... const content = useContent({ source: 'source-name', query: { dataQuery: 'query' } });...
Takes in the content source config object ({source, query, inherit, staticMode}
) and fetches the data. For all intents and purposes, it works identically to the Consumer’s fetchContent
function in both terms of input and output - it will return the data fetched from the content source. For more information about the parameters can be passed to useContent, see “fetchContent()” section in the Consumer API documentation.
useEditableContent
import { useEditableContent } from 'fusion:content';import { useComponentContext } from 'fusion:context';
export default () => { // Receive global content const { globalContent: content } = useComponentContext();
// Retrieve two functions from the useEditableContent hook const { editableContent, editableField } = useEditableContent();
return ( <h1 {...editableContent(content, 'headlines.basic')}> {/*Check that both the content and the headline exists before rendering the inline edited headline*/} {content && content.headlines ? content.headlines.basic : ''} </h1> );};
This hook will return four functions:
- EditableContent
- EditableField (for editableField, please consult the linked page as to how that function might be used)
- SearchableContent
- SearchableField
The child components can then receive the content of the function’s results, which the editor will then check to see if it’s a contentEditable tag. Once you make an inline change, then the editor will remember the next time you render it as well.
You can also set up a multi-nodal editableContent like so:
import { useEditableContent } from 'fusion:content';import { useComponentContext } from 'fusion:context';
export default () => { const { globalContent: content } = useComponentContext(); const { editableContent } = useEditableContent();
return ( <> <h1 {...editableContent(content, { headline: 'headlines.basic', subheadlines: 'subheadlines.basic', description: 'description.basic', })} > {content && content.headlines ? content.headlines.basic : ''} </h1> <h3> {content && content.subheadlines ? content.subheadlines.basic : ''} </h3> <p> {content && content.description ? content.description.basic : ''} </p> </> );};
Once the editableContent receives an object with multiple keys as the second param, it will create a multi-nodal component. Now, if you click on the headline, Editor will display a window on which you can make updates for the next two texts as well. Refresh after making the update and the texts should be updated accordingly.
Note that this will also trigger the “A component is contentEditable
and contains children
managed by React…” warning, just to let you know that the component is now inline-editable.