paldepind
paldepind

Reputation: 4870

How to modify the DOM directly in ReactJS

Let's say I have two arrays selectedFoobars and unselectedFoobars. These are my data and they are rendered as lists next to each other using ReactJS.

When the user clicks on an element in one of the lists I want to remove the element from that list, and add it to the end of the other list. That part is pretty straight forward using React.

But, I want the clicked element to sweep across the screen from its old position to its new position in the other list. If the user clicks on and element in the middle of the unselectedFoobars that element should animate across the page to the bottom of the selectedFoobars list.

I don't just want the moved element to fade out it the first list and fade in in the second. That would have been easy though, by using the animation hooks provided the animation addon for React.

That is one – as far as I can tell – valid example of a problem where one needs to modify the DOM directly to achieve the desired result.

Using Backbone.js one could easily do the DOM manipulation manually. This is straight forward and pretty clean in Backbone-world albeit quite but a bit of work. In AngularJS I'd create a directive. It would be pretty unidiomatic Angular. But it would get the job done.

What is the cleanest way to handle this and similar cases where direct DOM manipulation is needed using ReactJS?

Upvotes: 4

Views: 7570

Answers (1)

reecer
reecer

Reputation: 86

To manipulate a React component's "actual DOM" you can grab a reference of it using getDOMNode().

However, referencing the "actual DOM" is not necessarily the only solution. For instance, instead of separating your foobars into selected/unselected arrays, you could pool them into a single array where each item specifies itself as being selected or not. For example:

getInitialState: function(){
  return {
    foobars: [ {text: 'item1', selected: false} ]
},

render: function(){
  return this.state.foobars.map(function(item){
    return <Foobar selected={item.selected}>{ item.text }</Foobar>;
  });
}

Then your Foobar component could set the className based on this.props.selected. You could then utilize the animation addon or some other CSS3 transition technique.

Upvotes: 5

Related Questions