添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Almost EVERYONE who tried headless systems said they saw benefits. Download the state of CMS now!

Storyblok now on AWS Marketplace: Read more

O’Reilly Report: Decoupled Applications and Composable Web Architectures - Download Now

Empower your teams & get a 582% ROI: See Storyblok's CMS in action

Skip to main content

How to render dynamic component defined in JSON using React

Try Storyblok

Storyblok is the first headless CMS that works for developers & marketers alike.

With React it is easy to render dynamic components utilizing JSX and React.createElement , which we can utilize to render content with specific components and layouts by only using their name.

Section titled A basic content JSON that should be rendered A basic content JSON that should be rendered

The content JSON below contains an array called body which consists of multiple objects with different fields and one attribute called component which allows us to determine what component we should use to render its actual content.

        
      const data = {
  content: {
    body: [
        _uid: "BUY6Drn9e1",
        component: "foo",
        headline: "Foo"
        _uid: "gJZoSLkfZV",
        component: "bar",
        title: "Bar"
        _uid: "X1JAfdsZxy",
        component: "foo",
        headline: "Another headline"
    

Section titled Dynamic component rendering with React Dynamic component rendering with React

To allow us to render a JSON by dynamic components using their name we first have to loop through the array of components itself. Below you can see that we're using the map function to do exactly that.

Section titled Looping through the content array Looping through the content array

        
      function App() {
  return (
    <div className="App">
      {data.content.body.map(block => block.component)}
    

Section titled Creating components dynamically Creating components dynamically

Now to actually use the React component instead of only outputting their name we will pass the name of the component to a custom function called Components .

        
      function App() {
  return (
    <div className="App">
      {data.content.body.map(block => Components(block))}
    

To allow the component itself to access the current instance properties we're using the block object and pass it down to the React component we will create. We use block or blok in our tutorials as they are not "components" but instances of them filled with specific values.

Section titled Create and include your components Create and include your components

We're using two nested components one is called foo and the other one is called bar . We choose to create a components/ folder to have them at one place.

        
      import React from "react";
export default props => (
  <div className="foo">
    Hi I'm a Foo component with the headline:
    <h2>{props.block.headline}</h2>
    

Once created we need to set-up the custom Components function we were talking about earlier. First we will create a components.js in our root folder right next to our index.js . There we will start by importing our components from the components folder itself

        
      import React from "react";
import Foo from "./components/Foo";
import Bar from "./components/Bar";
    

Next we will define one object that maps the React components to the name we have given the components in the content JSON itself:

        
      import React from "react";
import Foo from "./components/Foo";
import Bar from "./components/Bar";
const Components = {
  foo: Foo,
  bar: Bar
    

Now all that's left for us to do is to write a function that checks if a component with a specific name exists. Since we're passing down the whole block in our JSX template we're able to access the block.component and look for that content in our newly created Components object.

        
      import React from "react";
import Foo from "./components/Foo";
import Bar from "./components/Bar";
const Components = {
  foo: Foo,
  bar: Bar
export default block => {
  // component does exist
  if (typeof Components[block.component] !== "undefined") {
    return React.createElement(Components[block.component], {
      key: block._uid,
      block: block
    

We can also create an anonymous component for the case that we didn't yet create or include a component of a specific name so we tell the user directly to create the missing component rather than throwing an exception.

        
      import React from "react";
import Foo from "./components/Foo";
import Bar from "./components/Bar";
const Components = {
  foo: Foo,
  bar: Bar
export default block => {
  // component does exist
  if (typeof Components[block.component] !== "undefined") {
    return React.createElement(Components[block.component], {
      key: block._uid,
      block: block
  // component doesn't exist yet
  return React.createElement(
    () => <div>The component {block.component} has not been created yet.</div>,
    { key: block._uid }