4 ms·
No, it's not for purity's sake. Integrating D3 with React is a real pain, because you essentially have a split brain problem where both D3 and React control the
by tracyhenry 6y ago
No, it's not for purity's sake. Integrating D3 with React is a real pain, because you essentially have a split brain problem where both D3 and React control the DOM. In complex cases involving things like transitions, you should wish yourself the best in not messing up the order in which DOM operations happen. And there is also huge performance benefits in letting only React control the DOM. I think the post has been amazing at illustrating how to translate D3 operations into JSX to get the best of both worlds.
- codethief 6y ago> Integrating D3 with React is a real pain, because you essentially have a split brain problem where both D3 and React control the DOM. I agree with you here but > there is also huge performance benefits in letting only React control the DOM. Compared to using d3 to operate on the DOM directly?[0] Do you have any benchmarks to back that up? Because in my experience, d3 is incredibly fast. Then again, maybe we're thinking about different applications? (Most of my experience is with animating stuff with d3.) [0]: Whether or not React is used alongside with it should not matter much, I think, as long as one doesn't trigger re-rendering of the React DOM.
- tracyhenry 6y agoI don't have a benchmark but I was referring to the case where some D3 APIs (e.g. zoom, force) seem to create more animation frames than needed, and interfere with other React state changes. I probably should do this experiment myself now that I see the elegant solution proposed in the OP. Also, if you use Ref, you are re-rendering the entire thing on every state change whereas React can do the diff with vdom. Ofc you can do the diff yourself with D3 code but it is less automatic.
- hogFeast 6y agoBingo. Even when you aren't doing animation frames, if you want to structure your app in a reusable way then you are (if you aren't careful) going to get lots of re-renders. If you are using hooks, and have useState/useEffect/useReducer it is very easy to go wrong. It also isn't re-inventing the wheel. d3 and React are based on fundamentally different models of programming (d3 is very imperative). I have done two or three pretty complex charting apps, and the only way to really break that cycle is to use the dispatcher which allows you to break up the flow of d3...you still end up with a ton of cruft, and lots of confusing constructs (you have to be very specific about what state is needed where and when...for example, some constructs in d3 require data immediately i.e. an axis, and others do not i.e. line, and some constructs require other constructs i.e. the dependency between lines and axis...clearly this conflicts with the data flow of your typical React app quite heavily).
- tptacek 6y agoI think you can more easily convince me that D3 and React don't go together at all, because their models conflict, than that it makes sense to code directly to D3's guts and replace a lot of its logic with React's. But you all have more experience with this than I do (I've used both in anger independently, but not together). There's a point in this article where they've replaced D3's axes code with a new React implementation. "Okay! So this is definitely more code. But that makes sense, since we're basically duplicating some of the d3 library code, in our own code base." I mean, yes. It makes sense. But it is, ceteris paribus, way worse than D3, where axes generation is kind of a fundamental basic idiom of the library, which we're here replacing with idiosyncratic new code. I get that the code might be better in some other direction, but just as code, it's worse. The claim is that it's more readable, but: it's only more readable if you don't do a lot of D3. To me this is shades of people trying to talk about Lisp function names or APL or whatever.
- chrisweekly 6y ago"ceteris paribus" -> "all else equal"
- totololo 6y agoDid you mean, at iso-circumjacentium? :p
- hogFeast 6y agoI think the issue is that when you try to make reusable charts, you end up doing this stuff anyway. You aren't replacing logic but you are coding around d3's logic. I 100% agree though, it is very janky. The issues aren't limited to the points you mention: state everywhere, errors getting swallowed, problems when you update (for example, the Axis component has a useMemo that renders once on load and doesn't change...this isn't a good idea because, presumably, you have to re-render on every update), on and on. The issue isn't d3 but making components reusable within React. d3's dispatch model fits well with React. But the data flow/dependencies just don't work with React at all (i.e. having to declare operations in a certain order). I am not 100% sure that the component library approach works. I get the idea but you need to actually tackle the problem of state and updating, which means working with the imperative model (i.e. not declaring your chart elements in React but using d3's imperative code, and hooking that into React's update cycle...for example, how would you use d3-brush with declarative code? Maybe I am missing something but it doesn't seem possible). I have no idea whether it is possible to integrate these two approaches fully...probably is but I surely don't know how (my approach so far is largely imperative, relies heavily on dispatching events, and splits state between data/chart constants/individual charts...I think it is possible to go further with hooks but I haven't had time to explore this fully...the declarative approach of actually writing svg elements and g elements seems too brittle).
- scotty79 6y agoI'm not quite sure. Transition React example is far from d3 version. It achieves only superficially similar result. d3 version is clear, flexible and composable but react version seems hacky and limited. I think putting d3 in useEffect is pretty perfect way of merging d3 and React DOM operations. What are the drawbacks?
- deleted 6y ago[deleted]
- austincheney 6y ago> And there is also huge performance benefits in letting only React control the DOM. How do you prove that with numbers?
- tracyhenry 6y agoI don't have numbers (see https://news.ycombinator.com/item?id=26630618 https://news.ycombinator.com/item?id=26630618 for my speculation). Regarding how I should confirm this is the case, I'd just run a controlled experiment and compare the frame rate produced by the two approaches.
- austincheney 6y agoThis is problematic for two reasons: 1. People make good faith assumptions on performance all the time and those assumptions tend to be either wrong or wildly inaccurately. The most important part of a performance difference is not that something is faster, but by how much faster it is. Without numbers to know the size of difference the conversation becomes meaningless. 2. People, particularly in the context of favorite frameworks and the DOM, regularly speak to performance complete out of context. They believe they are comparing like items when they aren't even remotely related. When it comes to performance there are typically only two things that are measured: execution time on the CPU or human writing time. When it comes to CPU execution time you need to start from the same state and end with an identical product for the comparison to be valid. A comparison between a React component and DOM manipulation aren't comparable enough to buy you that comparison. Its like comparing the production of a hammer factory to the speed of a nail gun.
- jiofih 6y ago> huge performance benefits in letting only React control the DOM That cannot be true. D3 is directly optimized for efficient updates, vs the comparatively inefficient virtual dom + diffing. Every performance oriented tool actually skips the react rendering lifecycle (even redux does that). Unless, of course, you’re triggering re-renders of the element D3 is controlling, which should not be the case.
- tracyhenry 6y agoFirst, I don't have numbers so everything is speculation. Second, I didn't say that pure React is faster than pure D3. Instead I said that pure React could be faster than React + D3 (using Ref). See https://news.ycombinator.com/item?id=26630618 https://news.ycombinator.com/item?id=26630618 for the reasoning.