0.0.8-alpha3 • Published 4 years ago

concave v0.0.8-alpha3

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

🧐 Concave

A Lens-like interface for state management in React.

Overview

Introduction to Lenses for React developers

Installation

API

stateful<S>(initialState: S): [Lens<S>, MutableRefObject<S>]

stateless<S>(): [Lens<S>, LensProvider<S>]

LensProvider<S>

Lens<A>

A stateless Proxy around A

Lens<A>.use(shouldUpdate? ShouldUpdate<A>): [ProxyValue<A>, UpdateFn<A>]

Lens<A>.$key

Examples

Testing

Performance tips

  1. Use shouldUpdate.

  2. If do use a shouldUpdate argument for the lens, you can either memoize it with React.useMemo or React.useCallback or store it outside of the component.

Example

Uses TypeScript and Proxy to dynamically construct a lens-like interface for your application state.

You can construct a lens/React Provider by just providing the shape of your application state

// LensProvider.ts

import { stateless } from "concave";
import type { State } from "./application-state";

export const [lens, LensProvider] = stateless<State>();
// App.tsx

import type { State } from './application-state';
import { Root } from './Root';
import { lens, LensProvider } from './LensProvider';

export const App = () => {
  const state: State = { ... };

  <LensProvider value={state} onChange={...}>
    <Root state={lens} />
  </LensProvider>
}

The lens can be focused by regular member access.

// Root.tsx

import { Lens } from "concave";
import type { State } from "./application-state";
import { Profile } from "./Profile";

type Props = {
  state: Lens<State>;
};

export const Root = (props: Props) => {
  return <Profile state={props.state.user.profile} />;
};

And then the underlying data it can be accessed by collapsing the lens into a React hook with use.

// Profile.tsx
import { Lens } from "concave";

type Props = {
  state: Lens<{ name: string; email: string }>;
};

const Profile = (props: Props) => {
  const [name, updateProfileName] = props.state.name.use();
  const [email, updateProfileEmail] = props.state.email.use();

  return (
    <>
      <input type="text" value={name} onChange={(ev) => updateProfileName(() => ev.target.value)} />
      <input type="email" value={email} onChange={(ev) => updateProfileEmail(() => ev.target.value)} />
    </>
  );
};
0.2.0

4 years ago

0.1.0

4 years ago

0.0.25

4 years ago

0.0.24

4 years ago

0.0.23

4 years ago

0.0.22

4 years ago

0.0.21

4 years ago

0.0.20

4 years ago

0.0.19

4 years ago

0.0.18

4 years ago

0.0.17

4 years ago

0.0.16

4 years ago

0.0.15

4 years ago

0.0.14

4 years ago

0.0.13

4 years ago

0.0.12

4 years ago

0.0.11

4 years ago

0.0.10

4 years ago

0.0.10-alpha3

4 years ago

0.0.10-alpha2

4 years ago

0.0.10-alpha1

4 years ago

0.0.9

4 years ago

0.0.9-alpha4

4 years ago

0.0.9-alpha3

4 years ago

0.0.9-alpha2

4 years ago

0.0.9-alpha1

4 years ago

0.0.8

4 years ago

0.0.8-alpha5

4 years ago

0.0.8-alpha4

4 years ago

0.0.8-alpha3

4 years ago

0.0.8-alpha2

4 years ago

0.0.8-alpha1

4 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago