ReactJS和呈现纯HTML

6

首先,我完全是React的新手,所以不确定我的代码是否已经按照“React方式”编写。

到目前为止,我已经创建了几个React类,用于呈现Bootstrap Modal。为了设置初始状态,我在componentsDidMount函数中调用了一个Ajax函数。这个方法可以正常工作,直到我尝试将纯HTML插入到modal body中。

服务器请求很好地完成了,并且我在this.state.data.content中得到了纯HTML代码,但是如果我尝试将其插入到modal body中,则会收到以下错误:

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.

有人知道如何解决吗?我在这里做对了吗?

谢谢!

<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>

你应该关闭<Modal.Body>标签吗?我认为设置dangerouslySetInnerHTML={this.rawMarkup()}的代码应该是 Modal.Body 的属性,而不是“子级”。 - Icepickle
这就是ReactBootstrap的标记方式。但你说得对,在这种情况下我需要一个额外的<div>标签才能让它正常工作。 - Flo Ragossnig
1个回答

7

看起来,您需要在希望渲染原始HTML的位置缺少一个div标签

考虑像这样更改Modal.Body代码

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

否则,渲染将会出现问题,因为您的标记实际上无法设置为Modal.Body元素的子元素。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接