Lens JS as Application State Manager

Lens-js library overview and experiments with cats.





Data is, in fact, an important part of your future application or stand-alone library. Their structure, integrity are important, as well as the approaches to organizing their storage and processing. The task, frankly, is not trivial, especially on the scale of corporate projects. One solution is to use a state manager, one of which will be discussed here.





Lenses

So what are Lenses? The easiest way to answer is thesis - lenses are:





  • the principle of organizing work with data, where they are quantized by individual nodes in one large directed graph;





  • aggregator (reducer), which assembles all individual quanta according to all the rules of the functional paradigm;





  • an interface that provides access to the data of each quantum;





  • and lastly, the lens ensures data integrity and relevance in your application.





It should be noted here that we are not talking about any implementation yet. Lens is a good fairy tale for those who are already tired of Redux, MobX, etc., or are developing some specific module where it is problematic to use popular state managers. There are many lens implementations. Try them all!





How does it all work?

, - . . ! ! …





react-lens-cats, . — lens-js, TypeScript React — lens-ts react-lens.





: , . . — , .





:





export interface Cat {
    name: string;
}

export interface Queue {
    cats: Cat[]
}

export interface Store {
    street: Queue;
    circle: Queue;
}
      
      



lens.ts







import { Lens } from '@vovikilelik/react-ts';

const murzic: Cat = { name: 'Murzic' };
const pushok: Cat = { name: 'Pushok' };
const sedric: Cat = { name: 'Sedric' };
const rizhik: Cat = { name: 'Rizhik' };

const store: {lens: Store} = {
    lens: {
        street: { cats: [murzic, pushok, sedric, rizhik] },
        circle: { cats: [] }
    }
};

export const lens = new Lens<Store>(
    () => store.lens,
    (value, effect) => {
        store.lens = value;
        effect();
    }
);
      
      



? , "".





, lens



, . , "".





, . ? , Test.tsx



.





import { lens } from './lens';

export Test: React.FC = () => (
    <div>
      { lens.go('circle').go('cats').get().map(c => c.name).join(' ') }
      { lens.go('street').go('cats').get().map(c => c.name).join(' ') }
    </div>
);
      
      



. , , , , .





Autosubstitution of attached properties

, ! - ! , circle



street



. , , . , , , , :





import { Lens } from '@vovikilelik/lens-ts';
import { useLens } from '@vovikilelik/react-lens';
import { Cat } from './lens';

export Cats: React.FC = (cats: Lens<Cat[]>) => {
    const [catsArray] = useLens(cats);
    return (
      <div>
          { catsArray.map(c => c.name).join(' ') }
      </div>
    );
}
      
      



Test.tsx



:





import { lens } from './lens';

export Test: React.FC = () => (
    <div>
        <Cats cats={lens.go('circle').go('cats')} />
        <Cats cats={lens.go('street').go('cats')} />
    </div>
);
      
      



. ? , ? Test.tsx



, - - Lunapark.tsx



:





import { Lens } from '@vovikilelik/lens-ts';
import { Queue } from './lens';

export Lunapark: React.FC = (street: Lens<Queue>, circle: Lens<Queue>) => (
    <div>
        <Cats cats={street.go('cats')} />
        <Cats cats={circle.go('cats')} />
    </div>
);
      
      



. ...





. , , , , , .





, , , . , useLens



.





, . Lunapark.tsx



, .





const popCat = (lens: Lens<Cat[]>): Cat | undefined => {
    const cats = lens.get();
    const cat = cats.pop();
    lens.set(cats);

    return cat;
}

const playCat = (lens: Lens<Cat[]>, cat: Cat) => {
    lens.set([...lens.get(), cat]);
}

export Lunapark: React.FC = (street: Lens<Queue>, circle: Lens<Queue>) => {
  const onCatPlay = useCallback(() => {
     const cat = popCat(street.go('cats'));
     cat && playCat(circle.go('cats'), cat);
  }, [street, circle]);
  
  return (
    <div>
        <Cats cats={street.go('cats')} />
        <Cats cats={circle.go('cats')} />
        <button onClick={onCatPlay} />
    </div>
  );
}

      
      



, useLens



, . . cats, , , — , .





, .





- ?

— , - , . , . , BabylonJS Web- . . Redux , , , . …





, ? . . - — .





! :





  • ;





  • ;





  • organize event-driven routines;





  • create abstractions to work with other approaches to state management.





Links

  1. Wiki on the lens-js





  2. Project with cats on lens-js





  3. Package react-lens on npm





  4. Package lens-ts on npm





  5. Package lens-js on npm





  6. Article about other lenses





  7. Another interesting post about lenses












All Articles