cvalentina
cvalentina

Reputation: 173

Using methods of react component in native dom element

I'm using React with Fluxxor to create a tree like visual component. For each node in the tree I want to provide basic functionality like deleting/editing the node or adding a new child. So every node has its own dropdown menu for these actions, the dropdowns are done with MaterializeCss Framework, and initially I created each of them inside the render method but then that cause a React error which I solved by rendering the a tag trigger inside the render function, and the ul that is used for the menu is created in the componentDidMount function using Jquery's append on the body element. The problem is that I want to map each of these actions to functions define in the React component, but it doesn't work out and it never gets called, how can I do this?

var ItemOferta = React.createClass({
    mixins: [FluxMixin],
    componentDidMount: function() {
        var id = "dd"+this.props.item.self.id;
        $("body").append(
            "<ul id='"+id+"' class='dropdown-content'>"+
            "<li><a href='javascript:void(0)'>Agregar hijo</a></li>"+
            "<li><a href='javascript:void(0)'>Editar</a></li>"+
            "<li><a href='javascript:void(0)' onclick='"+this.eliminar+"'>"+
            "Eliminar</a></li></ul>");
    },
    componentWillUnmount: function(){
        var id = "#dd"+this.props.item.self.id;
        $(id).remove();
    },
    eliminar: function(e){
        console.log("En el metodo eliminar");
        this.getFlux().actions.eliminarNivel(this.props.item.self.id);
    },
    render: function(){
         ...
         <div className="acciones">
             <a href="#" className="accion dropdown-button" 
                data-activates={"dd"+this.props.item.self.id}>
                <i className="mdi-navigation-more-vert"></i>
             </a>
         </div>
        ...
        );
    }
});

I omitted some code of the render method, I only posted the code for the dropdown trigger, as you can see in the onclick attribute I try to bind the this.eliminar function, but when I check it with the Chrome tools all appears is this function () { [native code] }.

Upvotes: 1

Views: 866

Answers (1)

Deepak
Deepak

Reputation: 2531

What you are doing is against React's principle. Changing the DOM elements will make React's DOM diffing absurd. You can fix your code like below. But highly not recommended.

componentDidMount: function() {
    var id = "dd"+this.props.item.self.id;
    var ulMarkup = "<ul id='"+id+"' class='dropdown-content'>"+
                   "<li><a>Agregar hijo</a></li>"+
                   "<li><a>Editar</a></li>"+
                   "<li><a class='eliminar'>Eliminar</a></li></ul>"

    var ulElement = $(ulMarkup).appendTo('body');

    $(ulElement).find("a").click(function() { return false; });
    $(ulElement).find("a.eliminar").click(this.eliminar);
}

The correct approach of doing it the React way would be like below.

render: function(){
     ...
     <div className="acciones">
         <a href="#" className="accion dropdown-button" 
            data-activates={"dd"+this.props.item.self.id}>
            <i className="mdi-navigation-more-vert"></i>
         </a>
         <ul className='dropdown-content'>
           <li><a>Agregar hijo</a></li>
           <li><a>Editar</a></li>
           <li><a onClick={this.eliminar}>Eliminar</a></li>
         </ul>
     </div>
    ...
}

Upvotes: 1

Related Questions