3 ms·
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 nam
by lobster_johnson 12y ago
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.
- dandelany 12y agoSeems 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.
- STRML 12y agoThis is the right answer. This will effectively keep React from touching the element ever again after the initial render.
- talldan 12y agoI'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.
- iyn 12y agoCan 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.
- talldan 12y agoDo 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.
- spicyj 12y agoNever 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.
- mbrock 12y agoIt 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).