And now there is a big pitfall that is called out on the docs in terms of performance, and it's because you're doing all that kind of work before the browser is painting, so you are blocking it. So code which you should be running in useEffect shouldn't necessarily be moved to a useLayoutEffect. But we can make this change. So we'll swap it in for useEffect, it will run synchronously, and that initial left value actually gets applied before the browser gets painted. So now we have effectively fixed our problem, and that works. But there are some downsides, and there are some things that make this maybe not the optimal solution. But we'll come back to them later on in the talk.
So, isn't this talk about refs? Well, yes, it is. So we are used to seeing refs defined in this way. So we say, useRef, it gives us this ref object, and then we pass this to the ref prop on our development, and that will be assigned asynchronously. But if we inspect the type of the ref property, as well as the ref object, which we can pass it, there's also a ref callback. And so what this means is you can actually define a function. And this function, when passed to the ref property, is going to behave in this way. So when a dev element is, or whatever element you apply it to, is mounted by React, this callback will be called with a reference to that HTML element. And then when, for whatever reason, that element is maybe removed from the DOM, this callback will again be called but with none. Well, this is the way it works in React 18, at least. And it's very important, if you follow this approach, that you wrap this with useCallback. Or maybe when you start using Compiler, that might not be required anymore. Because any time, if you didn't use useCallback, it would be a new function, it would force a render, and then you get into this, you could get into a bit of a loop. So you remember the useCallback for this approach. So as I said, it's called when it's mounted, it's called again with null when it's unmounted, and this runs synchronously before paint. And also in version 18, it's not impacted by strict mode. So this is how we could update our code to use a ref callback. So when the ref is given to us and it is defined, we can set up our listening so that we can adjust the left position. And because it's running synchronously, that initial one, we're able to set the position before it's rendered. And then another nice thing about this approach is that we've now got rid of those renders completely. So all of the renders that we did have, where we were updating the state or having things, have gone. But the end result is we've still got this really nice, smooth browser operating, because the only code that is now running is our code from AG Grid, to work out where it needs to be, and then to set that browser style. So we've basically chopped off all the React code, which was just duplicating what we knew how to do already. Now, with React 19, nearly here, these are some changes that are actually affecting the ref callback approach.
Comments