Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reactjs and rendering plain HTML

First of all I'm totally new to react so I'm not sure if my code is already written the "react way".

So far I've created a couple of react classes which render a Bootstrap Modal. To set the initial states I call an Ajax function within the componentsDidMount function. This works fine until I try to insert plain HTML into the modal body.

The server request works fine and I get plain HTML code in my this.state.data.content but if I try to insert this into the modal body I receive following error:

Error: Invariant Violation: Objects are not valid as a React child (found: object with keys {__html}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons.

Does anyone know how to fix this? Am I even doing the right thing here?

Thanks!

<script type="text/babel">

    var Modal = ReactBootstrap.Modal;
    var Button = ReactBootstrap.Button;
    var ButtonToolbar = ReactBootstrap.ButtonToolbar;


    var L5fmHeaderButton = React.createClass({

        render: function() {
            var iconClass = "glyphicon " + this.props.buttonIcon;
            return(
                <button onClick={this.props.onClick} className="lfm-Modal-Button">
                    <span className={iconClass} aria-hidden="true"></span>&nbsp;
                    {this.props.buttonText}
                </button>
            );
        }
    });

    var L5fmModalBody = React.createClass({

        rawMarkup: function() {
            return { __html: this.props.content };
        },

        render: function() {

            return(
                <Modal.Body>
                    dangerouslySetInnerHTML={this.rawMarkup()}
                </Modal.Body>
            );
        }

    });

    var L5fmModal = React.createClass({

        getInitialState : function() {
            return {
                data : []
            };
        },

        componentDidMount: function() {
            $.ajax({
                url: 'L5fm/setInitialState',
                dataType: 'json',
                cache: false,
                success: function(data) {
                    this.setState({data: data});
                    console.log(data);
                    console.log(this.state.data);
                }.bind(this),
                error: function(xhr, status, err) {
                    console.error(this.props.url, status, err.toString());
                }.bind(this)
            });
        },

        changeDirectory : function() {
            if (this.state.privateDir) {
                this.setState({privateDir: false});
            }
            else {
                this.setState({privateDir: true});
            }
        },

        render: function() {

            if(this.state.data.privateDir) {
                var browseIcon = "glyphicon-folder-open";
                var browseText = "browse all files";
            }
            else {
                var browseIcon = "glyphicon-briefcase";
                var browseText = "browse private files";
            }

            return(

                <Modal {...this.props} bsSize="large" aria-labelledby="contained-modal-title-lg">
                    <Modal.Header closeButton>
                        <div className="header-button-group">
                            <L5fmHeaderButton buttonIcon="glyphicon-cloud-upload" buttonText="upload" />
                            <L5fmHeaderButton buttonIcon="glyphicon-list" buttonText="list View" />
                            <L5fmHeaderButton onClick={this.changeDirectory} buttonIcon={browseIcon} buttonText={browseText} />
                        </div>
                </Modal.Header>
                    <L5fmModalBody content={this.state.data.content}/>
                </Modal>
            );
        }

    });


    var App = React.createClass({
        getInitialState: function() {
            return { lgShow: false };
        },
        render: function() {
            let lgClose = () => this.setState({ lgShow: false });

            return (
                    <ButtonToolbar>
                       <Button bsStyle="primary" onClick={()=>this.setState({ lgShow: true })}>
                           Launch large demo modal
                       </Button>

                       <L5fmModal show={this.state.lgShow} onHide={lgClose} />
                    </ButtonToolbar>
            );
        }
    });

    ReactDOM.render(<App />, document.getElementById("modal"));

</script>
like image 329
Flo Ragossnig Avatar asked Dec 29 '15 14:12

Flo Ragossnig


People also ask

Can you render HTML in React?

React's goal is in many ways to render HTML in a web page. React renders HTML to the web page by using a function called ReactDOM.render() .

Is it possible to use React without rendering HTML?

Yes it is very much possible and very much useful, in case of lazy loading components.

Is React better than plain HTML?

What makes React such a desirable library to learn is that it doesn't replace HTML. It takes advantage of HTML's popularity and strength as the most popular programming language, by letting you use a very similar syntax to HTML to build interfaces and add dynamic features to it using JavaScript.

Why use React over plain HTML?

It allows writing custom components React comes with JSX, an optional syntax extension, which makes it possible to write your own components. These components basically accept HTML quoting and also makes all subcomponent rendering a delightful experience for developers.


1 Answers

Well, as it seems, you are missing a div-tag where you wish to render your raw html

considering changing the Modal.Body code like this

var L5fmModalBody = React.createClass({
    rawMarkup: function() {
        return { __html: this.props.content };
    },
    render: function() {
        return(
            <Modal.Body>
                <div dangerouslySetInnerHTML={createMarkup()} />
            </Modal.Body>
        );
    }
});

otherwise the rendering gets broken because your markup cannot really be set as a child on the Modal.Body element

like image 140
Icepickle Avatar answered Sep 17 '22 23:09

Icepickle