Guide
React mixitup takes a list of keys to determine what to render.
If you have a list of images like:
const images: { id: string; src: string } = [
/* a lot of images */
];
then you have to convert these into a list of keys:
const imageKeys = images.map(({ id }) => id);
In order to access the src of the image within a renderCell
function you must create a dictionary mapping each id to a image.
const dir = Object.fromEntries(images.map(img => [img.id, img]));
The code will then look like this:
const [images, setImages] = React.useState<{ id: string; src: string }>([
/* a lot of images */
]);
const imageKeys = images.map(({ id }) => id);
const dir = Object.fromEntries(images.map(img => [img.id, img]));
return (
<ReactMixitup
keys={keys}
renderCell={(key, style, ref) => {
const image = dir[key];
return (
<img
src={img.src}
key={key}
ref={ref}
style={{
// You must set the transition property here!
transition: 'transform 300ms linear',
...style
}}
>
{key}
</img>
);
}}
transitionDuration={300}
/>
);
Finally to update, and animate the update, all you have to do is change the order of the images, e.g.
setImages(
images.slice(0).sort((a, b) => {
return a.localeCompare(b) * (DESC ? -1 : 1);
})
);
renderCell arguments
Only the key
, style
and ref
are the arguments which you must use. The render function also gets passed some additional arguments, but I've not found a good use case for them except for debugging purposes.
They are described on the API page.
renderWrapper
If you have a border around the wrapper holding the elements which should be animated, then you probably want the border to be animated if the number of inner items grow and shrink.
The container can only change size in one direction, either vertical or horizontal, see the API and the section regarding dynamicDirection
for examples of this.
When adding a renderWrapper
function it is important to pass the ref, style and cells to the returned JSX element.
return (
<ReactMixitup
keys={keys}
dynamicDirection="vertical"
transitionDuration={300}
renderCell={(key, style, ref) => {
// ...
}}
renderWrapper={(style, ref, cells) => (
<div ref={ref} style={{ ...style, borderBottom: '1px solid black' }}>
{cells}
</div>
)}
/>
);