Hacker News new | past | comments | ask | show | jobs | submit login

Hi, how does React work with other libraries that modify DOM state arbitrarily? How might d3 dom changes or canvas context calls work with React



Nice, we're actually posting a tutorial in a week or two about how we use d3 + react. I'll try to summarize though.

In the case that a library modifies the DOM, we try to keep React out of it's way. React works best when it has full control of the DOM. In these cases, React components are more of "wrappers" for the 3rd party libraries. Mostly by using the componentDidMount/componentWillUnmount to initialize/destroy the third party library, respectively. And props as a way of giving the parent a way of customizing the behavior of the third party library that the child wraps.


We use Google ads in our React apps, and it turns out to be a problem. I wonder if anyone has solved it in a satisfactory way.

Basically, with GPT you have named slots identified by their DOM element IDs. You can "refresh" a slot any time, which will populate the element if it's empty, or load a different ad.

So we do that when we're mounted. Unfortunately, if the page structure changes, React will re-render the component and blow away the contents -- anything GPT has put in the element is considered alien.

That's fine, we just refresh. The problem is knowing _when_ a render has finished and the ad element is empty. In my testing, React elements would often have a delay after which their changes have been applied to the DOM; so I use setInterval to check repeatedly for an empty element. It seems like a stupid solution, but I couldn't figure out a more solid way; there's no React callback for completed renders.


Seems to me you could wrap ad elements in container components that have:

shouldComponentUpdate() { return false; }

Which would prevent React from re-rendering them after initial mount... any reason why this doesn't work? I do this often when using d3 selections to keep React out of the way and catch incoming props in componentWillReceiveProps instead.


This is the right answer. This will effectively keep React from touching the element ever again after the initial render.


I'm intrigued as to why you think this approach is better than using a key? The 'shouldComponentUpdate' way of doing things means any changes to props or state on the component have to be handled manually, which can introduce a lot of non-trivial and overly complex code.


Do you have the 'key' prop specified on these components? React uses the key to keep track of a particular element. If you specify your own unique key, react will know that the dom representation of a component matches your react instance, and thus not replace the dom element when changes happen in a parent component (apart from if the component or parents are completely unmounted).

Without the implicitly set key, react creates its own index, so if a change happens in the hierarchy above your component, a new key might be given by react, causing the dom element to potentially be replaced when rendering.


Never used Google Ads, but you should be able to do something like

  var GoogleAd = React.createClass({
    getInitialState: function() {
      return {
        id: makeUniqueId()
      };
    },
    render: function() {
      // Since this is always the same, React won't try to change the contents
      return <div id={this.state.id} />;
    },
    componentDidMount: function() {
      googletag.defineSlot('/1234567/sports', [728, 90], this.state.id);
    },
    componentWillUnmount: function() {
      // Clean up the slot and any other resources here
    }
  });
and then not worry about it.


It would probably be good to supply a `key` property to the div to ensure that React never tries to reuse it (say, when changing from one GoogleAd to another).


Can you somehow use store to... store the ads? Like use getInitialState() to load the ads and use render() to just display it. I feel that you want to use regular MVC, while in React you should think of one-directional data flow (flux architecture). I probably don't understand the problem here, maybe if you would provide more details/some code I/somebody could help.





Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: