This adds refs to View Transition that can resolve to an instance of:
```js
type ViewTransitionRef = {
name: string,
group: Animatable,
imagePair: Animatable,
old: Animatable,
new: Animatable,
}
```
Animatable is a type that has `animate(keyframes, options)` and
`getAnimations()` on it. It's the interface that exists on Element that
lets you start animations on it. These ones are like that but for the
four pseudo-elements created by the view transition.
If a name changes, then a new ref is created. That way if you hold onto
a ref during an exit animation spawned by the name change, you can keep
calling functions on it. It will keep referring to the old name rather
than the new name.
This allows imperative control over the animations instead of using CSS
for this.
```js
const viewTransition = ref.current;
const groupAnimation = viewTransition.group.animate(keyframes, options);
const imagePairAnimation = viewTransition.imagePair.animate(keyframes, options);
const oldAnimation = viewTransition.old.animate(keyframes, options);
const newAnimation = viewTransition.new.animate(keyframes, options);
```
The downside of using this API is that it doesn't work with SSR so for
SSR rendered animations they'll fallback to the CSS. You could use this
for progressive enhancement though.
Note: In this PR the ref only controls one DOM node child but there can
be more than one DOM node in the ViewTransition fragment and they are
just left to their defaults. We could try something like making the
`animate()` function apply to multiple children but that could lead to
some weird consequences and the return value would be difficult to
merge. We could try to maintain an array of Animatable that updates with
how ever many things are currently animating but that makes the API more
complicated to use for the simple case. Conceptually this should be like
a fragment so we would ideally combine the multiple children into a
single isolate if we could. Maybe one day the same name could be applied
to multiple children to create a single isolate. For now I think I'll
just leave it like this and you're really expect to just use it with one
DOM node. If you have more than one they just get the default animations
from CSS.
Using this is a little tricky due timing. In this fixture I just use a
layout effect plus rAF to get into the right timing after the
startViewTransition is ready. In the future I'll add an event that fires
when View Transitions heuristics fire with the right timing.
react-test-renderer (DEPRECATED)
Deprecation notice
react-test-renderer is deprecated and no longer maintained. It will be removed in a future version. As of React 19, you will see a console warning when invoking ReactTestRenderer.create().
React Testing
This library creates a contrived environment and its APIs encourage introspection on React's internals, which may change without notice causing broken tests. It is instead recommended to use browser-based environments such as jsdom and standard DOM APIs for your assertions.
The React team recommends @testing-library/react as a modern alternative that uses standard APIs, avoids internals, and promotes best practices.
React Native Testing
The React team recommends @testing-library/react-native as a replacement for react-test-renderer for native integration tests. This React Native testing-library variant follows the same API design as described above and promotes better testing patterns.
Documentation
This package provides an experimental React renderer that can be used to render React components to pure JavaScript objects, without depending on the DOM or a native mobile environment.
Essentially, this package makes it easy to grab a snapshot of the "DOM tree" rendered by a React DOM or React Native component without using a browser or jsdom.
Documentation: https://reactjs.org/docs/test-renderer.html
Usage:
const ReactTestRenderer = require('react-test-renderer');
const renderer = ReactTestRenderer.create(
<Link page="https://www.facebook.com/">Facebook</Link>
);
console.log(renderer.toJSON());
// { type: 'a',
// props: { href: 'https://www.facebook.com/' },
// children: [ 'Facebook' ] }
You can also use Jest's snapshot testing feature to automatically save a copy of the JSON tree to a file and check in your tests that it hasn't changed: https://jestjs.io/blog/2016/07/27/jest-14.html.