Coder Social home page Coder Social logo

hooksy's Introduction

Hooksy

Hooksy is state managment solution based on react hooks

  • extremly easy to use
  • no boilerplate
  • works great with typescript
  • composable
  • injectable to any component with 1 line of code
  • allows creating complex data solutions (like actions, selectors) intuitively

demo

Tutorial

The best way to show how it works would be by example.

Let's assume we've got user store that is used by many components across the page. You can log in and out.

First - let's create the store:

// userStore.ts
import { createStore } from 'hooksy';

interface UserData {
  username: string;
}

const defaultUser: UserData = { username: 'Foo' };

export const [useUserStore] = createStore(defaultUser); // we've created store with initial value.
// useUserStore has the same signature like react useState hook, but the state will be shared across all components using it

Our store is ready and can be used inside any react component. If any component will modify user store state - all components using it will be re-rednered.

Let's see how we can use the store now:

import React from 'react';

import { useUserStore } from './userStore';

export function UserInfo() {
  const [user, setUser] = useUserStore();
  
  function login() {
    setUser({ username: 'Foo' })
  }

  return (
    <div>
      {!user && <strong>You're logged out<button onPress={login}>Login</button></strong>}
      {user && <strong>Logged as <strong>{user.username}</strong></strong>}
    </div>
  );
}

Now, we can also use the same store in totally different component:

import React from 'react';

import { useUserStore } from './userStore';

export function Footer() {
  const [user, setUser] = useUserStore();
  
  function logout() {
    setUser(null)
  }

  return (
    <div>
      {user && <strong>Press this button to log out: <button onPress={logout}>Log out</button></strong>}
    </div>
  );
}

If the logout button is pressed, both components using user store will get updated.

As you might notice - we've implemented login and logout actions inside components which might not be good idea. We can easily avoid that by creating custom hooks with all needed actions (and selectors or anything javascript will allow you to write)

Let's modify our user store definition

import { useCallback } from 'react';

import { createStore } from '../../src';

interface UserData {
  username: string;
}

export const [useUserStore] = createStore<UserData>(null); // user store is defined the same way as before

// custom hook 
export function useUser() {
  const [user, setUser] = useUserStore();

  // let's define custom actions (we can - and should - use useCallback hooks - later on)
  function logout() {
    setUser(null);
  }

  function login(username: string) {
    setUser({username})
  }

  return {
    user,
    logout,
    login,
  };
}

Now, we can modify our components eg:

import React from 'react';

import { useUser } from './userStore';

export function UserInfo() {
  const { user, login } = useUser();

  return (
    <div>
      {!user && <strong>You're logged out<button onPress={() => login({ username: 'Foo' })}>Login</button></strong>}
      {user && <strong>Logged as <strong>{user.username}</strong></strong>}
    </div>
  );
}

Avoiding re-renders when they're not needed

Let's say username is case insensitive and we want to re-render some component only when username is really changed eg 'Foo' changed to 'foo' should NOT cause re-render

To do that, we can use user store hook like

const [user, setUser] = useUserStore({ 
  shouldUpdate(oldUser, newUser) {
    return oldUser.username.toLowerCase() !== newUser.username.toLowerCase()
  }
})

Modify store state from outside of any component Let's say you want to log out user when some external event occurs. eg browser window get's closed etc

To do that, you can:

// userStore.ts
import { createStore } from 'hooksy';

interface UserData {
  username: string;
}

const defaultUser: UserData = { username: 'Foo' };

// NOTE 2nd tuple element allows us to update user store anywhere (and all components using it will get re-rendered)
export const [useUserStore, updateUser] = createStore(defaultUser); // we've created store with initial value.

// later on you can use it like
onSomeCustomBrowserEvent(() => {
  updateUser(null);
})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.