Hooshyar Qaderi
Hooshyar Qaderi

Reputation: 141

how can injection dynamic html element to page with next.js?

how can dynamic injection html element to page with next.js? that these elements Unknown type like(input, checkbox, img,...). this element specified with api that return json type like this:

[{
   "id":"rooms",
   "title":"Rooms",
   "order":1,
   "type":"string",
   "widget":"select",
   "data":[{
            "Id":18,
            "ParentId":null,
            "Title":"One",
            "Level":null,
            "Childrens":[]
           },
            {"Id":19,
            "ParentId":null,
            "Title":"Two",
            "Level":null,
            "Childrens":[]
           },
            {"Id":20,
            "ParentId":null,
            "Title":"Three",
            "Level":null,
            "Childrens":[]
           }]
},
{
   "id":"exchange",
   "title":"Exchange",
   "order":0,
   "type":"boolean",
   "widget":"checkbox",
   "data":[]
}]

my try is:

Index.getInitialProps = async function({req, query}) {

    const res= await fetch('url api')
    var elements= await res.json() 

    var test = () => (
        <div>
            {...... convert json to html elements.......}
        </div>
    )

    return {
        test
    }
})
function Index(props) {
   return(
      <a>
        {props.test}
      </a>
   )
}

result is null, mean nothing for presentation.

the question is, Do I do the right thing? Is there a better way?

Upvotes: 12

Views: 30278

Answers (1)

cross19xx
cross19xx

Reputation: 3487

What happens is that during the transfer of props from server to client in getInitialprops, JSON is serialized and so functions are not really serialized. See https://github.com/zeit/next.js/issues/3536

Your best bet is to convert the test data into a string of HTML data and inject it using dangerouslySetInnerHTML. An example will be:

class TestComponent extends React.Component {
    static async getInitialProps() {
        const text = '<div class="homepsage">This is the homepage data</div>';
        return { text };
    }

    render() {
        return (
            <div>
                <div className="text-container" dangerouslySetInnerHTML={{ __html: this.props.text }} />
                <h1>Hello world</div>
            </div>
        );
    }
}

The catch with this is that the string you return must be a valid HTML (not JSX). So notice I used class instead of className

You can read more about it here: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

Upvotes: 18

Related Questions