All Projects → ml-in-barcelona → react-rules-of-hooks-ppx

ml-in-barcelona / react-rules-of-hooks-ppx

Licence: BSD-2-Clause license
This ppx validates the rules of React hooks.

Programming Languages

reason
219 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to react-rules-of-hooks-ppx

awesome-ppx-reasonml
curated list of reasonml PPX rewriter
Stars: ✭ 28 (-30%)
Mutual labels:  ppx, reasonml
hello-ppx-esy
A simple example of a ppx with Reason and esy
Stars: ✭ 38 (-5%)
Mutual labels:  ppx, reasonml
jsoo-react
js_of_ocaml bindings for ReactJS. Based on ReasonReact.
Stars: ✭ 126 (+215%)
Mutual labels:  ppx, reasonml
bs-getenv
ReasonML/BuckleScript PPX for embedding env variables
Stars: ✭ 25 (-37.5%)
Mutual labels:  ppx, reasonml
refabricator
Static Site Generator for/in ReasonML
Stars: ✭ 31 (-22.5%)
Mutual labels:  reasonml
bs-axios
Bucklescript bindings for axios
Stars: ✭ 74 (+85%)
Mutual labels:  reasonml
tea-chess
A chess-themed tutorial on writing an SPA in Bucklescript-TEA
Stars: ✭ 28 (-30%)
Mutual labels:  reasonml
nibbledb
a byte-sized time series database
Stars: ✭ 23 (-42.5%)
Mutual labels:  reasonml
tensority
Strongly typed multidimensional array library for OCaml
Stars: ✭ 44 (+10%)
Mutual labels:  ppx
bacen-exchange-rates
Reason API to fetch the daily reports from BACEN PTAX exchanges
Stars: ✭ 16 (-60%)
Mutual labels:  reasonml
rembrandt
Simple UI framework written in Reasonml.
Stars: ✭ 81 (+102.5%)
Mutual labels:  reasonml
proxifier-rules
Rules for proxifiers programs: Proxifier
Stars: ✭ 51 (+27.5%)
Mutual labels:  ppx
ts2re
Convert TypeScript type declarations to Reason
Stars: ✭ 32 (-20%)
Mutual labels:  reasonml
bs-reason-apollo
ReactApollo bindings for BS
Stars: ✭ 23 (-42.5%)
Mutual labels:  reasonml
turaku-client
Web / Electron client application for Turaku
Stars: ✭ 27 (-32.5%)
Mutual labels:  reasonml
re-typescript
An opinionated attempt at finally solving typescript interop for ReasonML / OCaml.
Stars: ✭ 68 (+70%)
Mutual labels:  reasonml
re-cite
Manage citations from your colleagues , friends, movies, your cat or even yourself.
Stars: ✭ 20 (-50%)
Mutual labels:  reasonml
bs-decode
Type-safe JSON decoding for ReasonML and OCaml
Stars: ✭ 105 (+162.5%)
Mutual labels:  reasonml
vscode-graphiql-explorer
Use GraphiQL + GraphiQL Explorer to build your GraphQL operations, right from inside of VSCode.
Stars: ✭ 35 (-12.5%)
Mutual labels:  reasonml
markdown-reason-react
Generate ReasonReact Pages from Markdown
Stars: ✭ 17 (-57.5%)
Mutual labels:  reasonml

react-rules-of-hooks-ppx

STATUS: This project isn't complete and might give false-positives. Read more

This package is a no-op ppx rewriter. It is used as a 'lint' to enforce React's Rules of Hooks.

  • Exhaustive dependencies in useEffect
  • Order of Hooks
    • Hooks shoudn't be called in different order
    • Only Call Hooks at the Top Level

Why

One of the points of using Reason or ReScript is to have a compiler that warns about issues with your code, where functions expect different types from the given ones. That's Type-checking and works amazingly well, but there are some cases where even with the right types, the runtime of your program can cause issues. Very commonly in side-effects. I found this case while working with ReasonReact.

ReasonReact and useEffect hooks is one of those cases, where types ensures that the functions are called correctly, but they have certain rules that aren't cacheable at the type-system. Not following those rules might cause some unexpected bug or even a run-time error.

This package solves this problem, lints the use(Layout)Effect from your react.components based on the React's Rules of Hooks

Status

It's a proof of concept on re-creating the ESLint plugin, and it's very restrictive and not always useful in the Reason/ReScript context. Values are immutable by default, so functions or Modules from the exterior of a useEffect will not change at anytime during runtime. The only benefit is where state/props values are missing, which is a great addition to check your useEffects.

Install

npm install react-rules-of-hooks-ppx --save-dev
# or
yarn add react-rules-of-hooks-ppx --dev

Add the ppx on the BuckleScript config (bsconfig.json)

"ppx-flags": [
  "react-rules-of-hooks-ppx/Bin.exe"
]

You can disable globally both rules passing parameters to the ppx:

Disable "Exhaustive dependencies in useEffect"

"ppx-flags": [
  ["react-rules-of-hooks-ppx/Bin.exe", "-exhaustive-deps"]
]

Disable "Order of Hooks"

"ppx-flags": [
  ["react-rules-of-hooks-ppx/Bin.exe", "-order-of-hooks"]
]

Issues

Feel free to use it and report any unexpected behaviour in the issue section

Demo

Here we have a dummy react component:

[@react.component]
/* Recives a prop called "randomProp" */
let make = (~randomProp) => {
  let (show, setShow) = React.useState(() => false);

  /* We have a useEffect that re-runs each time that "show" changes it's value, and we want to update "show" when randomProp is true. */
  React.useEffect1(
    () => {
      /* Since this effect relies on "randomProp" and misses ont the dependency array, will cause undesired behaviour. */
      if (randomProp) {
        setShow(prevShow => !prevShow);
      }
      None;
    },
    [|show|],
  );

  <div />;
};

Produces the following error:

 6 | ..React.useEffect1(
 7 |     () => {
 8 |       if (randomProp) {
 9 |         setShow(_ => !show);
10 |       }
...
13 |       None;
14 |     },
15 |     [|show|],
16 |   ).

Error: ExhaustiveDeps: Missing 'randomProp' in the dependency array

Acknowledgements

Thanks to @jchavarri

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].