/react-universal-hooks

:tada: React Universal Hooks : just use****** everywhere (Functional or Class Component). Support React DevTools!

Primary LanguageJavaScriptMIT LicenseMIT

react-universal-hooks npm version

React Universal Hooks : just use****** everywhere. Support React >= 16.8.0

Installation

Using npm:

$ npm install --save react-universal-hooks

Or yarn:

$ yarn add react-universal-hooks

Usage

just add one line import!

index.js

import "react-universal-hooks";
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

  ReactDOM.render(
      <App />,
    document.getElementById('root'),
  );

Demo

https://codesandbox.io/s/jnnnw158j5

import React, { useState, useContext } from "react";
import { useWindowSize } from "./useWindowSize";

const MyContext = React.createContext({ myLabel: "MyContextLabel" });

const Functional = () => {
  const [count, setCount] = useState(0);
  const { width, height } = useWindowSize();
  const { myLabel } = useContext(MyContext);
  return (
    <React.Fragment>
      <p>{myLabel}</p>
      <p>{"Functional windowSize : " + width + "x" + height}</p>
      <p>{"Functional Counter " + count}</p>
      <button onClick={() => setCount(c => c + 1)}>Functional Counter</button>
    </React.Fragment>
  );
};

class Component extends React.PureComponent {
   constructor(props) {
      super(props);
      this.state = { /* your already existing business logic here */ };
    }
    componentDidMount (){ /* your already existing business logic here */}
    componentDidUpdate (){ /* your already existing business logic here */}
    componentUnmount (){ /* your already existing business logic here */} 
  render() {
    const [count, setCount] = useState(0);
    const { width, height } = useWindowSize();
    const { myLabel } = useContext(MyContext);
    return (
      <React.Fragment>
        <p>{myLabel}</p>
        <p>{"Component windowSize : " + width + "x" + height}</p>
        <p>{"Component Counter " + count}</p>
        <button onClick={() => setCount(c => c + 1)}>Component Counter</button>
      </React.Fragment>
    );
  }
}

useWindowSize.js (custom Hook example)

import { useState, useEffect } from "react";

export const useWindowSize = () => {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  });

  const handle = () => {
    setSize({
      width: window.innerWidth,
      height: window.innerHeight
    });
  };

  useEffect(() => {
    window.addEventListener("resize", handle);
    return () => {
      window.removeEventListener("resize", handle);
    };
  }, []);

  return size;
};

Why Universal Hooks?

  • use a customHook in your Component/Functional, without refactor.
  • useMemo & useCallback make PureComponents 100% pure! (max performance!)

Use Case : Make PureComponent 100% Pure

import { useCallback } from 'react';

class MyComponent extends React.PureComponent {
  render (){
    //....
  }
}

class Container extends React.PureComponent {
  render (){
    {this.props.arrayProp.map(el=>
      <MyComponent key={el.id} onClick={useCallback( ()=> someAction(el.id) , [el.id])} /> 
    )}
  }
}

Api Reference

Api Reference are the same as official ones, so you can see api reference @ https://reactjs.org/docs/hooks-reference.html
Currently supported api on Classes Component:

  • useState
  • useEffect
  • useLayoutEffect
  • useMemo
  • useCallback
  • useReducer
  • useRef
  • useContext
  • useImperativeHandle
  • useDebugValue

React Dev Tools

index.js

import { supportReactDevTools } from 'react-universal-hooks';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

supportReactDevTools ({ active: process.env!=="production" });

  ReactDOM.render(
      <App />,
    document.getElementById('root'),
  );

universal hooks devtools

How it works under the hood ?

https://github.com/salvoravida/react-class-hooks

Feedback

Let me know what do you think about!
Do you like it? Give a star to this project! :D

Contributors

See Contributors.

License

MIT License.