克隆反应组件及其子组件

时间:2017-02-08 13:28:14

标签: reactjs

我有三个组件,App,Row和Column。单击列组件可更改其文本状态。现在我想复制包含Column组件的Row组件。但是当我复制时,我得到Column组件的默认文本值,而不是更改的文本状态。

基本上,当我复制Row Component时,我希望Column组件具有更改的文本状态而不是其默认状态。我无法理解它,所以请帮助我。谢谢!

以下是我的代码:

App.js

class App extends React.Component {
    constructor() {
        super()
        this.addRow = this.addRow.bind(this)
        this.removeRow = this.removeRow.bind(this)
        this.duplicateRow = this.duplicateRow.bind(this)

        this.state = {
           rows: []
        }
    }

    addRow(){
       this.setState({
           rows: this.state.rows.concat(<Row />)
       });
    }

    removeRow(index){
        this.setState({
            rows: this.state.rows.filter((_, i) => i !== index)
        });
    }

    duplicateRow(index){
        const rows = this.state.rows;
        const dupli = this.state.rows[index];
        const insert = (rows, idx, newItem) => [
            ...rows.slice(0, idx),
            newItem,
            ...rows.slice(idx)
        ]
        const updatedRows = insert(rows, index, dupli);
        this.setState({
            rows: updatedRows
        });
    }

    render() {
        return (
            <div ref="htmlBuilder" className="html-builder container">
                <div ref="content">
                    {
                        this.state.rows.map( (obj, key) => <Row key={key} index={key} removeRow={this.removeRow} duplicateRow={this.duplicateRow} />)
                    }
                </div>
                <div className="pt-non-ideal-state" style={{border:"2px dashed #eee",width:"100%",maxWidth:"100%",paddingTop:30,paddingBottom:30}}>
                    <div className="pt-non-ideal-state-visual pt-non-ideal-state-icon" style={{margin:0}}>
                        <a href="javascrip:void(0)" onClick={this.addRow}><span className="pt-icon pt-icon-add"></span></a>
                    </div>
                </div>
            </div>
        )
    }
}

Row.js

class Row extends React.Component {
    constructor() {
        super();
        // bindingd
        this.showActions = this.showActions.bind(this);
        this.hideActions = this.hideActions.bind(this);
        this.removeRow = this.removeRow.bind(this);
        this.duplicateRow = this.duplicateRow.bind(this);
        // initial state
        this.state = {
            class: "row",
            actions: false,
            children: [<Column key={0.0} />]
        }
    }

    showActions(){
        this.setState({
            class: "row hb-editor",
            actions: true
        });
    }
    hideActions(){
        this.setState({
            class: "row",
            actions: false
        });
    }
    removeRow(){
        this.props.removeRow(this.props.index);
    }
    duplicateRow(){
        this.props.duplicateRow(this.props.index,this.render());
    }

    render() {
        let actions = "";
        if(this.state.actions){
            actions = <div style={{position:"absolute",top:0,right:0,backgroundColor:"#8BEEEB"}}>
                        <Duplicate action={this.duplicateRow} />
                        <Delete delete={this.removeRow} />
                    </div>
        }
        return (
            <div ref={this.props.index} className={this.state.class} onMouseOver={this.showActions} onMouseLeave={this.hideActions} style={{position:"relative",paddingTop:30,paddingBottom:30}}>
                {actions}
                {this.state.children}
            </div>
        )
    }
}

Column.js

class Column extends React.Component {
    constructor() {
        super();
        // bindings
        this.change = this.change.bind(this)
        // initial state
        this.state = {
            class: "col-md-12",
            text: "I am a column with class",
            children: [<Txt key="text" text={this.text} change={this.changeText} />]
        }
    }

    ComponentWillMount(){
        this.setState({
            text: this.props.text || this.state.text
        })
    }

    change(){
        const newText = "You changed me..."
        this.setState({
            text: newText
        })
    }

    text(text){
        text = text || "Click to change me"
        return text
    }

    render() {
        return (
            <div onClick={this.change} className={this.state.className}>
                {this.state.text} "{this.state.class}" 
                {
                    this.state.children.map( (obj, key) => obj)
                }
            </div>
        )
    }
}

0 个答案:

没有答案