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

Overview

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.

Comments
  • Page crashes when component with no hooks at all rerenders.

    Page crashes when component with no hooks at all rerenders.

    image image

    The component in question here isn't using any hooks at all, but the library is still trying to run inputsArrayEqual on it and getting an undefined length. This crashes the entire page.

    opened by FrobtheBuilder 19
  • Hook values don't show in react-devtools

    Hook values don't show in react-devtools

    The values for the useState hooks don't show in react-devtools (unlike standard hooks).

    Possible explanations

    1. React-devtools may explicitly check if a component is class-based, and if so, runs no hook-checking code.
    2. The hook mechanism used by react-universal-hooks differs from the official hooks, so react-devtools can't recognize them.

    Potential solutions

    1. If cause is no. 1: Somehow trick react-devtools into thinking class-based components are functional ones, so it runs the hook-checking code.
    2. If cause is no. 2: Modify the hook mechanism in this library to match that of the official hooks.

    Workaround

    In the meantime, I've come up with a workaround for accessing the hook data, by wrapping the hooks and having them store their data (using object-mutation to prevent re-renders) on something like component.state.hookValues.

    The component is accessible from the hooks because I have a currentCompBeingRendered = this line run at the start of each render function. (I already auto-wrap the render function of components, so I was able to just add to that)

    Here are the areas of code accomplishing my workaround: (in this case, the type of hook exposed is a variant of useSelector from react-redux, but you could use the same approach for any hook type)

    opened by Venryx 6
  • Why isn't this included with React?

    Why isn't this included with React?

    I thought this was too good to be true. We've got a codebase full of class components that we're currently localizing with i18next, but we didn't want to resort to wrapping everything with a HOC. The translation hook shipped with react-i18next seems to work perfectly with the built-in React hooks shimmed using this library and we can literally just call useTranslation in our class render methods, as long as we're careful to follow the ordinary hook rules. This library of yours is an absolute lifesaver and I'm shocked that it isn't more popular. It also makes me wonder why in the name of all that is holy that the React team didn't include this compatibility layer in the core of React.

    Thank you so much for making this thing. I am forever in your debt.

    opened by FrobtheBuilder 4
  • Problem with Edge when bundled directly due to package.json module property.

    Problem with Edge when bundled directly due to package.json module property.

    In this library you included a "module" property in package.json, which points directly to the source code. This property specifies to bundlers that the module should be included directly, using the es6 module syntax. It does not, however, mark the code for any sort of transpilation if it uses features that aren't present in all browsers. See: https://github.com/rollup/rollup/wiki/pkg.module#wait-it-just-means-import-and-export--not-other-future-javascript-features. This library uses the object spread rest syntax, which, while generally well supported by most browsers, is not technically part of the es6 (ES2015) standard and in particular, still is not supported in Edge. That means if you import the library directly, it will crash the entire page because the spread syntax is preserved in the outputted bundle. image image

    This means the user will need to use import "react-universal-hooks/dist" rather than import "react-universal-hooks" if they want Edge support.

    The solution to this problem would be to add another compiled build, one targeting es6, and point the "module" property to it instead of the source.

    opened by FrobtheBuilder 2
  • Bump acorn from 7.1.0 to 7.1.1

    Bump acorn from 7.1.0 to 7.1.1

    Bumps acorn from 7.1.0 to 7.1.1.

    Commits
    • 6d19489 Mark release 7.1.1
    • 793c0e5 More rigorously check surrogate pairs in regexp validator
    • b5c1787 Fix incorrect comment in regexp parser
    • 12ae8fe Parameterize dummy value and export isDummy
    • fa3ad8c Further refine acorn-walk types
    • 1d50286 Fix some errors in walk types
    • 97801f0 Mark acorn-walk 7.1.1
    • e9372c1 Further clean up walker types
    • de6edeb Remove NarrowNode from walk.d.ts
    • 1d85e7c Fix: acorn-walk type work with acorn's
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Compatibility issues with mobx-react

    Compatibility issues with mobx-react

    See here for details: https://github.com/salvoravida/react-class-hooks/issues/4

    (I'm only creating this mirror issue here so that if others hit it while integrating with mobx-react, and they search the issues section, they can find it.)

    opened by Venryx 1
  • Bump eslint-utils from 1.3.1 to 1.4.2

    Bump eslint-utils from 1.3.1 to 1.4.2

    Bumps eslint-utils from 1.3.1 to 1.4.2.

    Commits
    • 4e1bc07 1.4.2
    • e4cb014 🐛 add null test
    • 230a4e2 1.4.1
    • 08158db 🐛 fix getStaticValue security issue
    • 587cca2 🐛 fix getStringIfConstant to handle literals correctly
    • c119e83 🐛 fix getStaticValue to handle bigint correctly
    • 531b16f 🔖 1.4.0
    • 276303d ⚒ upgrade rollup
    • cb518c7 🐛 fix hasSideEffect false negative
    • aac472e 🐛 fix isParenthesized had false positive on ImportExpression (fixes #1)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump lodash from 4.17.11 to 4.17.14

    Bump lodash from 4.17.11 to 4.17.14

    Bumps lodash from 4.17.11 to 4.17.14.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
    dependencies 
    opened by dependabot[bot] 1
  • not working with react 16.3.2

    not working with react 16.3.2

    I've done the following,

    import 'babel-polyfill';
    import 'whatwg-fetch';
    import 'react-hot-loader/patch';
    import React from 'react';
    import ReactDOM from 'react-dom';
    ... extra code here....
    
    ReactDOM.render(
      <Root store={ store } history={ history } />,
      document.getElementById('wheniwork-app')
    );
    

    but i still get https://cl.ly/41d88eae2db5/Image%202019-04-09%20at%2012.22.40%20PM.png in a child of that main.js file... am i missing something?

    opened by th3fallen 1
  • Bump ansi-regex from 4.1.0 to 4.1.1

    Bump ansi-regex from 4.1.0 to 4.1.1

    Bumps ansi-regex from 4.1.0 to 4.1.1.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump minimist from 1.2.5 to 1.2.6

    Bump minimist from 1.2.5 to 1.2.6

    Bumps minimist from 1.2.5 to 1.2.6.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Releases(v0.5.1)
Owner
Salvatore Ravidà
senior software engineer / full remote
Salvatore Ravidà
React Native APIs turned into React Hooks for use in functional React components

React Native Hooks React Native APIs turned into React Hooks allowing you to access asynchronous APIs directly in your functional components. Note: Yo

React Native Community 2.9k Sep 22, 2022
Agnostic functional state machine with epic type support

Agnostic functional state machine with epic type support

Christian Alfoni 53 Sep 3, 2022
Use-ref-deps-effect - Effect hooks that support ref.current dependency

use-ref-deps-effect Effect hooks that support "ref.current" dependency Install n

BYUNGI 5 Jun 22, 2022
Simple global state for React with Hooks, which just depends on React's useEffect and useState.

react-hooks-simple-global-state Simple global state for React with Hooks, which just depends on React's useEffect and useState. The idea here is simpl

Ayrton Everton 4 Aug 5, 2022
🍹 A lot of nice hooks to make react hooks easier to use ( useState callback / life cycle / instance variable)

?? Nice Hooks 中文版 A lot of nice hooks to make react hooks easier to use. If you find this project is useful to you, please give me a star. Installatio

Daniel.xiao 45 May 5, 2022
Use-supabase-hooks contains react hooks for common supabase functions, with type safety!

Use-supabase-hooks contains react hooks for common supabase functions, with type safety!

Anurag 14 Sep 30, 2022
Use-p2 - React hooks for p2-es. Use this in combination with react-three-fiber

yarn add @react-three/p2 React hooks for p2-es. Use this in combination with re

Poimandres 100 Sep 5, 2022
React Hook to track the visibility of a functional component

react-intersection-visible-hook React hook to track the visibility of a functional component based on IntersectionVisible Observer. In the following e

Avraam Mavridis 50 Dec 31, 2021
React Hook to force your functional component to update.

useForceUpdate useForceUpdate is a React Hook that forces your function component to re-render. useForceUpdate does not serve a purpose in and of itse

Charles Stover 170 Sep 21, 2022
A delightful modal dialog component for React, built from the ground up to support React Hooks.

?? modali A delightful modal dialog library for React, built from the ground up to support React Hooks. Modali provides a simple interface to build be

Upmostly 204 Sep 23, 2022
[OUTDATED]Ponyfill for the React Hooks API (Support RN)

react-with-hooks Polyfill and ponyfill for the React Hooks API. Works on React Native! ⚠️ The code on master branch is still WIP. Install $ npm i reac

Wei Zhu 152 Feb 2, 2022
🎙 A simple React hook for detecting the use of an Ad Blocker by the user. Built-in TS support.

useDetectAdBlocker ?? A simple React hook for detecting the use of an Ad Blocker by the user. Built with TypeScript (built-in type safety and support)

Filippo Fonseca 0 Dec 23, 2021
ReactJs Custom hooks, component lifecycle - Indispensable hooks

ReactJs Custom hooks, component lifecycle - Indispensable hooks

Alan Buscaglia 54 Sep 23, 2022
Just a quick playing with React 17, TypesScript and using VsCode as the main editor

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

Heriberto Magaña 1 Dec 7, 2021
👩‍🍳 A React Hooks utility library containing popular customized hooks

React Recipes A React Hooks utility library containing popular customized hooks What's your favorite dish? npm i react-recipes --save yarn add react-r

Craig Walker 905 Sep 19, 2022
🔥 A collection of beautiful and (hopefully) useful React hooks to speed-up your components and hooks development 🔥

A collection of beautiful (and hopefully useful) React hooks to speed-up your components and hooks development ?? Live playground here ?? ???? English

Antonio Rù 6k Sep 22, 2022
Learn the more advanced React hooks and different patterns to enable great developer APIs for custom hooks

?? Advanced React Hooks ?? EpicReact.Dev Learn the more advanced React hooks and different patterns to enable great developer APIs for custom hooks. W

José Gonçalves 4 Mar 15, 2022
React-api-query - Hooks to use react-query with a typed API client

?? react-api-query Hooks to use react-query with a typed API client. More types,

Felix Gnass 4 Aug 10, 2022
Use immer to drive state with a React hooks

use-immer A hook to use immer as a React hook to manipulate state. Installation npm install immer use-immer API useImmer useImmer(initialState) is ver

immer 2.4k Sep 25, 2022