Ad

Is There Reactjs Have Auto Switch Render? (renderToStaticMarkup, RenderToString)

- 1 answer

I render server and client side with same jsx. I need some element only have html, and do not need data-reactid. (e.g. A pure html jsx layout has some dynamic variable but do not need data-reactid).

And i except i can reuse the server side render dom which contains data-reactid, and do not need rerender the view.

The other element has data-reactid which can do not need rerender by reactjs. Cannot use shouldComponentUpdate because 'renderToString' method do not call shouldComponentUpdate.

I don't except i should render two element with different function( e.g. renderToStaticMarkup, renderToString) and combine it because the element could be include by many element. Render split and combine could cause mistake when element is much more.

Here is my fantasy:

In this case, i want {this.props.children} have data-reactid but the outside html and budy (DefaultLayout) do not.

class DefaultLayout extends  React.Component{   
        if (typeof window !== 'undefined') {
            return (
                <div>{this.props.children}</div>
            );
        } 
        return (
        <html>
            <head>
            </head>
            <body>
                <div id="container" className='container'>
                    <div>{this.props.children}</div>
                </div>
                <script src='/js/index.js'type='text/javascript'></script>
            </body>
        </html>
        );
    }
};
DefaultLayout.noNeedDiffCompoment = true;
export default DefaultLayout;

or a new pure html Compoment

class DefaultLayout extends  React.PureHtmlComponent{    

        if (typeof window !== 'undefined') {
            return (
                <div>{this.props.children}</div>
            );
        }
        return (
        <html>
            <head>
            </head>
            <body>
                <div id="container" className='container'>
                    <div>{this.props.children}</div>
                </div>
                <script src='/js/index.js'type='text/javascript'></script>
            </body>
        </html>
        );
    }
};
export default DefaultLayout;

and i can use this layout easly and not error in client side and server side.

class Somepage extends  React.Component {
    constructor(props) {
        super(props);
    }

    render(){
        return (
            <DefaultLayout>
                <h1>Hello world</h1>
            </DefaultLayout>
        );
    }
};

If i write as above, the render function can auto swap render function to render elements.

Is there any graceful solution like this?

Ad

Answer

in this case you should use the famous dangerouslySetInnerHTML instead of props.children.

There's no other solution.

const DefaultLayout = ({html}) => (
    <html>
        <head>
        </head>
        <body>
            <div id="container" className='container' dangerouslySetInnerHTML={html} />
            <script src='/js/index.js'type='text/javascript'></script>
        </body>
    </html>
);
export default DefaultLayout;

and...

const html = renderToString(<App />);
return renderToStaticMarkup(<DefaultLayout html={html} />);
Ad
source: stackoverflow.com
Ad