Adrian Ribao
Adrian Ribao

Reputation: 1439

How can I append external DOM to React component?

I have a page with a form rendered in the server, it handles validation, and the correct value for the selects.

I want to hide the DOM of that form, and append it into a react component so I can use it in react-router.

const NewItem = React.createClass({  
  render() {                          
    return (                          
      <div>                           
        <h1>New item</h1>
        {/* I WANT THE FORM FROM THE PAGE HERE*/}
      </div>                          
    )                                 
  }                                   
})                                    

What is the best way to do it?

Upvotes: 6

Views: 17361

Answers (3)

David I. Samudio
David I. Samudio

Reputation: 2693

React > 16.3

Try using portals like in this component:

import {Component} from 'react';
import {createPortal} from 'react-dom';
import PropTypes from 'prop-types';

class DOMPortal extends Component {
    constructor(props) {
        super(props);
        this.el = document.createElement(props.component);
    }

    componentDidMount() {
        this.props.parentEl.appendChild(this.el);
    }

    componentWillUnmount() {
        this.props.parentEl.removeChild(this.el);
    }

    render() {
        return createPortal(
            this.props.children,
            this.el,
        );
    }
}

DOMPortal.propTypes = {
    parentEl: PropTypes.object.isRequired,
    component: PropTypes.string,
};

DOMPortal.defaultProps = {
    component: 'div',
};

Now you can pass your external DOM reference as the parentEl props to it:

<DOMPortal parentEl={decorator.contentWidget.domNode}>...children</DOMPortal>

React < 16.3

Using this.refs is "deprecated", try this instead :

render() {
 return <div ref={(DOMNodeRef) => {
                 this.componentRef=DOMNodeRef;
                }}>
      ...
      </div>;
 }

Then this.componentRef will be accesible in componentDidMount() so you can append your external DOM element:

componentDidMount(){
  this.componentRef.appendChild(externalDOMelement);
}

Notes:

Remember that this.componentRef changes over time (renders()), so you must update it wherever you are passing it to.

Check for a defined reference before using it: if(this.componentRef){// ... your code}

Functional Components' refs are handled differently.

Source:

React Doc

Upvotes: 2

Japesh
Japesh

Reputation: 261

React gives us the functionality dangerouslySetInnerHTML. it gives us the support of adding HTML element. for example

function createMarkup() {
  return {__html: 'First &middot; Second'};
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}

You can also use portals introduced in react-16 for appending React component anywhere in the tree by using following code.

ReactDOM.createPortal(child, container)

follow following link Portals for refference

Upvotes: 1

August Lilleaas
August Lilleaas

Reputation: 54593

You have full access to the DOM in componentDidMount. You can use refs to access the specific DOM element you want.

var NewItem = React.createClass({
    componentDidMount: function () {
        this.refs.formTarget.appendChild(myFormDomElement);
    },

    render: function () {
        return React.DOM.div(null,
            React.DOM.h1(null, "New item"),
            React.DOM.div({ref: "formTarget"}));
    }
});

Note that in 0.14, a ref is a raw DOM element. Prior to that a ref was a react component and you had to call React.findDOMNode(it) to get the actual DOM element.

Upvotes: 2

Related Questions