在 React 组件中动态创建元素

Nic*_*ock 8 html javascript reactjs

我创建了一个辅助函数,当我单击按钮时,它可以在组件中动态创建元素。但是它没有显示我尝试附加到父 div 的 html 的一半。

它正确地将标签添加为 html,但其余部分只是纯文本。谁能明白为什么吗?

用于动态创建内容的函数:

function addElement(parentId, elementTag, elementId, html) {
    let parentElement = document.getElementById(parentId);
    let elementToAdd = document.createElement(elementTag);
    elementToAdd.setAttribute('id', elementId);
    elementToAdd.innerHTML = html;
    parentElement.appendChild(elementToAdd);
}
Run Code Online (Sandbox Code Playgroud)

我的组件中的功能:

static addMatch() {
    let html = "<div className=\"form-group\"><label className=\"control-label\">Add Match</label>" +
        "<DatePickerselected={this.state.startDate}onChange={this.handleChange.bind(this)}/></div>";
    addElement('fixture-parent', 'newMatch', uuid(), html);
}
Run Code Online (Sandbox Code Playgroud)

我的完整反应组件如下:

import React, {Component} from "react";
import DatePicker from "react-datepicker";
import {addElement} from "../../helpers/DynamicElementsHelper";
import moment from "moment";
const uuid = require('uuid/v1');

require('react-datepicker/dist/react-datepicker.css');

class Fixtures extends Component {

    constructor() {
        super();
        Fixtures.addMatch = Fixtures.addMatch.bind(this);
        this.state = {
            startDate: moment()
        };
    }

    handleChange(date) {
        this.setState({
            startDate: date
        });
    }

    static addMatch() {
        let html = "<div className=\"form-group\"><label className=\"control-label\">Add Match</label>" +
            "<DatePicker selected={this.state.startDate} onChange={this.handleChange.bind(this)} /></div>";
        addElement('fixture-parent', 'newMatch', uuid(), html);
    }

    render() {
        return (
            <div className="tray tray-center">
                <div className="row">
                    <div className="col-md-8">
                        <div className="panel mb25 mt5">
                            <div className="panel-heading">
                                <span className="panel-title">Fixtures</span>
                                <p>A list of fixtures currently on the system, pulled in via ajax from Ratpack</p>
                            </div>
                            <div className="panel-body p20 pb10">
                                <div id="fixture-parent" className="form-horizontal">
                                    <div className="form-group">
                                        <label className="control-label">Add Match</label>
                                        <DatePicker
                                            selected={this.state.startDate}
                                            onChange={this.handleChange.bind(this)}/>
                                    </div>
                                </div>
                            </div>
                            <button onClick={Fixtures.addMatch }>Add Match</button>
                        </div>
                    </div>
                </div>
            </div>
        );
    }

    }

    export default Fixtures;
Run Code Online (Sandbox Code Playgroud)

Sam*_* I. 3

在React中,建议不要直接与DOM交互。相反,您应该根据您拥有的数据修改 JSX。对于您的代码,您应该更改状态并基于此显示信息,而不是添加包含更改状态数据的 HTML 标记:

addMatch() {
    //Add a start date to the list of starting dates
    this.setState({
        listOfStartDates: [...this.state.listOfStartDates, newDate]
    }); 
}

render(){
    //For each starting date, generate a new 'match' as you called them
    // note: this is the same as the stringyfied HTML tag OP had in the question
    let listOfMatches = this.state.listOfStartDates.map((date)=>{
        return (
            <div className="form-group">
                <label className="control-label">
                    Add Match
                </label>
                <DatePicker selected={date} onChange={this.handleChange.bind(this)} />
            </div>
        );
    /* then in here your returned JSX would be just as OP originally had, with the exception that you would have {listOfMatches} where OP used to have the inserted list of HTML tags */
    return //...
}
Run Code Online (Sandbox Code Playgroud)

由于每次状态更改时组件都会重新渲染,因此组件将始终具有与开始日期一样多的匹配项。

希望有帮助!