A small ~1kb, Hook-based library for creating Reactive-UI in Vanilla.

Last update: Jun 9, 2022

Vanic

A small, Hook-based library for creating Reactive-UI in Vanilla.

ci npm version License download-url gzip

Features

  • Reactive-UI.
  • Hooks.
  • No compiler and build-tool required.
  • Jsx & literals HTML.

Install

NPM or Yarn

npm i vanic
// or
yarn add vanic

Browser

">

<head>
  <script src="//unpkg.com/vanic">script>
head>

ES Module

import { html, render } from "https://esm.sh/vanic"; // more code ">
<body>
  ...
  <script type="module">
    import { html, render } from "https://esm.sh/vanic";
    
    // more code
  script>
body>

Deno

/** @jsx h */
import { h, render, useState } from "https://deno.land/x/[email protected]/mod.ts";

// more code

Usage

Jsx

Note: jsx requires build-tools.

{ const [count, setCount] = useState(0); useEffect(() => { // log counter console.log(count); }, [count]); return (

{count}

) } render(Counter, document.getElementById("app"));">
/** @jsx h */
import { h, Fragment, render, useState, useEffect } from "vanic";

const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // log counter
    console.log(count);
  }, [count]);

  return (
    <Fragment>
      <button onClick={() => setCount(count + 1)}>Click Me</button>
      <h2>{count}</h2>
    </Fragment>
  )
}

render(Counter, document.getElementById("app"));

Literals Html

{ const [count, setCount] = useState(0); useEffect(() => { // log counter console.log(count); }, [count]); return html`

${count}

`; } render(Counter, document.getElementById("app"));">
import { html, render, useState, useEffect } from "vanic";

const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // log counter
    console.log(count);
  }, [count]);

  return html`
    <div>
      <button onclick="${() => setCount(count + 1)}">Click Mebutton>
      <h2>${count}h2>
    div>
  `;
}

render(Counter, document.getElementById("app"));

For syntax highlight, just install vscode extensions for literal html lit-html.

Usage in browser

">
<html>
  <head>
    <script src="//unpkg.com/vanic"></script>
  </head>
  <body>
    <div id="app"></div>
    <script>
      const { html, render, useState } = Vanic;
      //more code here
    </script>
  </body>
</html>

Server Side

{ return

Hello Home

} const str = renderToString(Home); console.log(str); // send in the server.">
/** @jsx h */
import { h, renderToString, useState } from "vanic";

const Home = () => {
  return <h1>Hello Home</h1>
}

const str = renderToString(Home);
console.log(str);
// send in the server.

Passing props in literals

html`

${props.text}

`; const Home = () => { return html`
${Title({ text: "My Title" })}

Welcome

`; } render(Home, document.getElementById("app"));">
import { html, render } from "vanic";

const Title = props => html`<h1>${props.text}h1>`;

const Home = () => {

  return html`
    <div>
      ${Title({ text: "My Title" })}
      <h2>Welcomeh2>
    div>
  `;
}

render(Home, document.getElementById("app"));

Hooks

UseState

const [state, setState] = useState(0);

UseEffect & UseLayoutEffect

useEffect(() => {
  // code
  return () => {
    // cleanup
  }
}, [/* deps */]);

UseReducer

const [state, dispatch] = useReducer(reducer, initial, /* initLazy */);

UseMemo

const value = useMemo(() => expensiveFunc(a, b), [a, b]);

UseCallback

const addTodo = useCallback(() => {
  setTodos((prev) => [...prev, "New Todo"]);
}, [todos]);

UseRef

const count = useRef(0);

Note: useRef for access DOM different from react.

Accesing DOM via useRef

const Home = () => {
  const input = useRef(null);

  return (
    <Fragment>
      <input ref={input}/>
      <button onClick={() => {
        input.ref().focus();
      }}>Focus Me</button>
    </Fragment>
  )
}

UseContext

Note: UseContext different from react.

{ return }); } render(App, document.getElementById("app"));">
const ThemeContext = createContext();

const Home = () => {
  const theme = useContext(ThemeContext);

  return <h1 style={{ color: theme.color }}>Hello Home</h1>
};

const App = () => {
  return ThemeContext.Provider({ color: "red" }, () => {
    return <Home/>
  });
}

render(App, document.getElementById("app"));

Custom Hook

Very simple with custom hook.

Example handling input.

{ const [input, handle] = useState(initState); return [ // object input input, // handling (e) => handle({ ...input, [e.target.id]: e.target.value }), // reset (obj = {}) => handle({ ...input, ...obj }) ] } const MyForm = () => { const [input, handleInput, resetInput] = useInput({ name: "", address: "" }); const onSubmit = (e) => { e.preventDefault(); console.log(input); // => { name: "foo", address: "bar" } // reset resetInput({ name: "", address: "" }) } return (
) } render(MyForm, document.getElementById("app"));">
/** @jsx h */
import { h, render, useState } from "vanic";

// example hook for handling input form.
const useInput = (initState) => {
  const [input, handle] = useState(initState);
  return [
    // object input
    input,

    // handling
    (e) => handle({ 
      ...input, 
      [e.target.id]: e.target.value 
    }),

    // reset
    (obj = {}) => handle({ ...input, ...obj })
  ]
}

const MyForm = () => {
  const [input, handleInput, resetInput] = useInput({
    name: "",
    address: ""
  });

  const onSubmit = (e) => {
    e.preventDefault();
    console.log(input);
    // => { name: "foo", address: "bar" }

    // reset
    resetInput({ name: "", address: "" })
  }

  return (
    <form onSubmit={onSubmit}>
      <input id="name" value={input.name} onChange={handleInput} />
      <input id="address" value={input.address} onChange={handleInput} />
      <button type="submit">Submit</button>
    </form>
  )
}

render(MyForm, document.getElementById("app"));

Style

Support style with object.

...
<div style={{ backgroundColor: 'red' }}>/* more */</div>
...

GitHub

https://github.com/herudi/vanic
You might also like...

Collection of hook-based memoized selector factories for declarations outside of render.

react-selector-hooks Collection of hook-based memoized selector factories for declarations outside of render. Motivation Reusing existing functions. I

Mar 11, 2022

Flexible React Hook to automatically update navigation based on scroll position

Flexible React Hook to automatically update navigation based on scroll position

react-use-scrollspy Installation react-use-scrollyspy is a React Hook which requires React 16.8.0 or later. // yarn yarn add react-use-scrollspy // or

Jun 15, 2022

A hook based project created during 20-Dec week ReactJS workshop

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Dec 25, 2021

💫 Tiny and powerful hook-based event system for React

BitAboutEvent 💫 Tiny and powerful hook-based event system for React. 100% Idiomatic React.

May 12, 2022

Automatically constructs the dependencies hook array for your (p)react hooks based on the dependencies used in the callback!

Automatically constructs the dependencies hook array for your (p)react hooks based on the dependencies used in the callback!

May 18, 2022

React hook library, ready to use, written in Typescript.

This is the repository for usehooks.ts, a Gatsby powered blog hosted with Github & netlify that publishes easy to understand React Hook code snippets.

Jun 19, 2022

A hooks-based lightweight React library for state management

React async states A naive lightweight React library for managing state. What is this ? This is a library for decentralized state management in React.

May 29, 2022

Collection of beginner-friendly real world examples of hook usage.

Hooks. People love them, people hate them. But one is for sure - hooks are there to stay and React ecosystem is going to evolve, again. The most impor

Oct 14, 2021

Easily manage the Google Tag Manager via Hook

Easily manage the Google Tag Manager via Hook

React Google Tag Manager Hook Use easily the Google Tag Manager With this custom hook, you can easily use the Google Tag Manager with 0 config, you ju

Jun 14, 2022
Comments
  • 1. Unable to run this code

    Unable to properly run the below code whereas the same looks good in preact.

    // import { h, render } from "preact";
    // import { useEffect, useState } from "preact/hooks";
    import { h, render, useState, useEffect } from "vanic";
    
    let A = () => {
    	useEffect(() => {
    		return () => console.log("clean effect All");
    	});
    	useEffect(() => {
    		console.log("effect");
    		return () => console.log("clean effect");
    	}, []);
    	return <div>A Component</div>;
    };
    
    const X = ({ what }: { what?: string }) => {
    	return <div>X {what}</div>;
    };
    
    const App = () => {
    	const [show, setShow] = useState(true);
    
    	return (
    		<div>
    			<X what={"some"} />
    			<X what={"some"} />
    			<X />
    			<button onclick={() => setShow(!show)}>Show</button>
    			{show ? <A /> : <div>Empty</div>}
    			<Counter />
    		</div>
    	);
    };
    
    function Counter() {
    	const [count, setCount] = useState(0);
    
    	useEffect(() => {
    		console.log(count);
    	}, [count]);
    	return (
    		<div>
    			<button
    				onclick={() => {
    					setCount(count + 1);
    				}}
    			>
    				Increment
    			</button>
    			<h1>Counter: {count}</h1>
    		</div>
    	);
    }
    
    render(<App/>, document.getElementById("app"));
    `
    Reviewed by kethan at 2022-06-17 16:54
A small package of custom React hooks that are useful for debugging changes in React hook dependencies across renders

use-debugger-hooks This is a package of custom React hooks that are useful for debugging dependency changes between renders. Most act as drop in repla

Jun 10, 2022
A small package that exposes a performant stopwatch UI component and hook.

@glamboyosa/react-stopwatch A small package that exposes a performant stopwatch UI component and hook. demo.mov Install npm install --save @glamboyosa

Nov 27, 2021
React hook for creating input values

@rehooks/input-value React hook for creating input values Note: This is using the new React Hooks API Proposal which is subject to change until React

May 7, 2022
A React custom-hook for creating flexible and accessible expand/collapse components.

A custom hook for creating accessible expand/collapse components in React. Animates the height using CSS transitions from 0 to auto.

Jun 23, 2022
A hook-based multistep wizard library with vast control over the logic of the user as per use-case.
A hook-based multistep wizard library with vast control over the logic of the user as per use-case.

A hooks-based multistep wizard (what I call it a machine ?? ) built for React which is flexible and easy to use. Huge shout out to jcmcneal for the Re

Feb 8, 2022
BitAboutState - Tiny and powerful React hook-based state management library
BitAboutState - Tiny and powerful React hook-based state management library

?? Tiny and powerful React hook-based state management library. 100% Idiomatic React.

May 22, 2022
Keep-react-hook-form - A lib to store react-hook-form values in session storage

Keep-react-hook-form - A lib to store react-hook-form values in session storage

Jan 27, 2022
useReactiveState() - a reactive alternative to React's useState()

useReactiveState() - a reactive alternative to React's useState() Installation $ npm install use-reactive-state Example // 'useReactiveState()' examp

Mar 8, 2022
Tiny utility package for easily creating reusable implementations of React state provider patterns.

react-state-patterns Tiny utility package for easily creating reusable implementations of React state provider patterns. ?? react-state-patterns makes

Feb 4, 2022
React hooks for creating a branching undo/redo history
React hooks for creating a branching undo/redo history

use-flexible-undo This lib gives you hooks and utilities for adding a branching undo history to your React project, or in general for experimenting wi

Mar 20, 2022