v4 of aframe-react improves performance, simplifies the API, adds full test coverage, and fixes all open issues in one sweep by changing how React passes down props to A-Frame.
Before
Props were serialized to strings (e.g., geometry={primitive: 'box', width: 5}
to geometry="primitive: box; width: 5
) and dumped into the DOM. A-Frame would receive updates through the DOM. The issues with this was that the logic for serialization was not solid, and going through the DOM was not performant because it meant we often would be serializing to strings only for A-Frame to parse it back into an object.
Other issues arose with A-Frame not being initialized when React was rendering DOM. Or React rendering React Components in isolation, attempting to initializing components on entities that were not attached to the DOM.
After
Props are passed directly to A-Frame through .setAttribute()
. A-Frame's .setAttribute()
s can handle objects, arrays, and other non-string data so no serialization or parsing is needed. aframe-react
uses React's refs to grab a handle on the DOM element, which ensures that the element has mounted before aframe-react
tries to pass any data. By removing all logic and passing directly through to A-Frame, things are much simpler and more performant by not having to touch the DOM. Everything is in memory.
onXXX
React-style handlers were removed in favor of the events
prop. onXXX
caused ambiguity in mapping to custom event names because event names could have hyphens, be lower case, be upper case, or a mix of lower case and upper case. The events
objects makes the event names explicit. onXXX
may also be confusing because in normal React, those map to events provided by the DOM (e.g., onClick
). In VR, these events are purely custom and synthetic.
events
now also correctly handles the removal or addition of event handlers when the events
prop is updated.
As a related change, since props are passed directly to A-Frame as-is, we can no longer pass coordinates in array form (e.g., position={[1, 2, 3]})
. We may pass them using objects (i.e., position={{x: 1, y: 2, z: 3}})
.