DataOptic
Optics make working with immutable state painless, but sometimes you may need to perform these immutable updates outside of global state created with createState.
Examples range from updating React state created with useState,
updating global state in a Redux reducer
or a Zustand action,
to manipulating your GraphQL cache directly with apollo-client.
A DataOptic is an Optic that's not focused on global state, but simply on a plain immutable value that you want to produce new versions of.
It retains all of the benefits of the Optics API but without the state management part (no subscribe method).
Usage
Call the focusOn function to create a DataOptic from a plain value.
tsimport {focusOn } from "@optics/react";constuser = {name : "John Doe",contact : {address : {number : 1,street : "Rue de la paix",},},credits : {gold : {available : 10,blocked : 3 },silver : {available : 30,blocked : 7 },},};constuserOptic =focusOn (user );
tsimport {focusOn } from "@optics/react";constuser = {name : "John Doe",contact : {address : {number : 1,street : "Rue de la paix",},},credits : {gold : {available : 10,blocked : 3 },silver : {available : 30,blocked : 7 },},};constuserOptic =focusOn (user );
- Call
seteverytime you want to apply a modification where the optic is currently focused.
It returns a newDataOpticfocused on the updated value. - Call
getto retrieve the final value that got all the previous updates applied to it.
tsconstupdatedUser =focusOn (user ).contact .address .number .set (10).credits .gold .available .set ((prev ) =>prev + 5).get ();
tsconstupdatedUser =focusOn (user ).contact .address .number .set (10).credits .gold .available .set ((prev ) =>prev + 5).get ();
It lets us update both the user's street number and his amount of available gold credits in a single expression.
ts// updatedUser{name: "Vincent",contact: {mails: "foo@bar.com",address: {number: 10,street: "Rue de la paix",},},credits: {gold: { available: 15, blocked: 3 },silver: { available: 30, blocked: 7 },},};
ts// updatedUser{name: "Vincent",contact: {mails: "foo@bar.com",address: {number: 10,street: "Rue de la paix",},},credits: {gold: { available: 15, blocked: 3 },silver: { available: 30, blocked: 7 },},};
@optics/data
The @optics/data package only exports DataOptic and the focusOn function, without the rest of the API related to state management.
You can import this package if you are already invested in another state management solution and just want to use Optics to perform immutable updates.