Skip to main content

Lists

With an optic focused on an array, it's often useful to derive an optic for each element of the array (e.g. to loop over these optics and render a list from it).

useOptic returns the getOptics function that lets you do exactly that:

tsx
import { useOptic } from "@optics/react";
 
type Props = {
usersOptic: Optic<User[]>;
};
 
const Users = ({ usersOptic }: Props) => {
const [, { getOptics }] = useOptic(usersOptic);
 
const optics = getOptics((user) => user.id);
 
return optics.map(([key, userOptic]) => (
<User key={key} userOptic={userOptic} />
));
};
tsx
import { useOptic } from "@optics/react";
 
type Props = {
usersOptic: Optic<User[]>;
};
 
const Users = ({ usersOptic }: Props) => {
const [, { getOptics }] = useOptic(usersOptic);
 
const optics = getOptics((user) => user.id);
 
return optics.map(([key, userOptic]) => (
<User key={key} userOptic={userOptic} />
));
};
Keys

The function you pass to getOptics is used to compute a key for each element in the array.
This is used to prevent the optics from being recreated when the array is modified. When an element changes place in the array, the optic focused on this element is reused and doesn't change reference.

Keys for optics serve pretty much the same purpose as keys in React.
In fact you can reuse the the generated key and pass it to the key prop of the component you render just like we did in the example above.

Mapped Optics

The getOpticsFromMapping function does the same thing but for mapped optics.

tsx
import { useOptic, mapped } from "@optics/react";
 
type Props = {
userMappedOptic: Optic<User, mapped>;
};
 
const Users = ({ userMappedOptic }: Props) => {
const [, { getOpticsFromMapping }] = useOptic(userMappedOptic);
 
const optics = getOpticsFromMapping((user) => user.id);
 
return optics.map(([key, userOptic]) => (
<User key={key} userOptic={userOptic} />
));
};
tsx
import { useOptic, mapped } from "@optics/react";
 
type Props = {
userMappedOptic: Optic<User, mapped>;
};
 
const Users = ({ userMappedOptic }: Props) => {
const [, { getOpticsFromMapping }] = useOptic(userMappedOptic);
 
const optics = getOpticsFromMapping((user) => user.id);
 
return optics.map(([key, userOptic]) => (
<User key={key} userOptic={userOptic} />
));
};