Adding component dynamically in React

0

I'm trying to dynamically add one component within another in React. So that I click on some element and that onClick it will add this component next to the specified div.

I tried to do this: (The object is added but not rendered)

import React from 'react';
import Draggable from 'react-draggable';
import { css } from 'glamor';
import Sortable from 'react-sortablejs';

/**
 *
 */
function getCSS() {
  return {
    square: css({
      width: 100,
      height: 100,
      border: '1px solid #000',
      cursor: 'move',
      display: 'inline-block',
      marginLeft: '10px',
      textAlign: 'center'
    }),
    circle: css({
      width: 100,
      height: 100,
      borderRadius: '50%',
      border: '1px solid #000',
      cursor: 'move',
      display: 'inline-block',
      marginLeft: '10px',
      textAlign: 'center'
    })
  }
}

/**
 *
 */
class DragDuplicate extends React.Component {

  /**
   *
   */
  createSquare() {
    console.log(1);
    document.getElementById('container').append(
      <Draggable>
        <div {...css.square}>Drag</div>;
      </Draggable>
    );
  }

  /**
   *
   */
  createCircle() {
    console.log(2);
    document.getElementById('container').append(
      <Draggable>
        <div {...css.circle}>Drag</div>;
      </Draggable>
    );
  }

  render() {
    let css = getCSS();
    return (
      <div>
        <div {...css.square} onClick={this.createSquare.bind(this)}>Drag</div>
        <div {...css.circle} onClick={this.createCircle.bind(this)}>Drag</div>
        <div {...css.square} onClick={this.createSquare.bind(this)}>Drag</div>
        <div {...css.circle} onClick={this.createCircle.bind(this)}>Drag</div>
        <hr />
        <div id="container"></div>
      </div>
    );
  }
}

export default DragDuplicate;
export { DragDuplicate };

Any example of doing this would help.

    
asked by anonymous 10.05.2017 / 23:26

1 answer

1

To render a react component, you can not intentionally use imperative APIs as element.append .

The way to change your status is to reflect what you want to render using .setState({...}) and use that information to render the changes in the render() method. I do not know if it works with your use of Draggable etc, but it's the idea:

class DragDuplicate extends React.Component {
  constructor(props) {
    super(props);
    this.state = {circleShown: false, squareShown: false};
  }    

  createSquare() {
    this.setState({
      squareShown: true,
    });
  }

  createCircle() {
    this.setState({
      circleShown: true,
    });
  }

  renderCircle(css) {
    if (!this.state.circleShown) return null;
    return (
      <Draggable>
        <div {...css.circle}>Drag</div>;
      </Draggable>
    );
  }

  renderSquare(css) {
    if (!this.state.squareShown) return null;
    return (
      <Draggable>
        <div {...css.square}>Drag</div>;
      </Draggable>
    );
  }

  render() {
    let css = getCSS();
    return (
      <div>
        <div {...css.square} onClick={this.createSquare.bind(this)}>Drag</div>
        <div {...css.circle} onClick={this.createCircle.bind(this)}>Drag</div>
        <div {...css.square} onClick={this.createSquare.bind(this)}>Drag</div>
        <div {...css.circle} onClick={this.createCircle.bind(this)}>Drag</div>
        <hr />
        <div id="container">
          {this.renderSquare(css)}
          {this.renderCircle(css)}
        </div>
      </div>
    );
  }
}
    
11.05.2017 / 16:36