@@ -301,20 +301,63 @@ hook alongside :ref:`use_effect` or in response to element event handlers.
301301**Rules of Hooks **
302302------------------
303303
304- Under construction... for now refer to
305- `React's documentation <https://reactjs.org/docs/hooks-rules.html >`_ on this topic.
304+ Hooks are just normal Python functions, but there's a bit of magic to them, and in order
305+ for that magic to work you've got to follow two rules. Thankfully we supply a
306+ `Flake8 Linter Plugin `_ to help enforce them.
306307
307- .. note ::
308308
309- We're `working on a linter <https://github.com/idom-team/idom/issues/202 >`_ to help
310- enforce the rules.
309+ Only call hooks at the top level
310+ --------------------------------
311+
312+ **Don't call hooks inside loops, conditions, or nested functions. ** Instead you must
313+ always call hooks at the top level of your functions. By adhering to this rule you
314+ ensure that hooks are always called in the exact same order. This fact is what allows
315+ IDOM to preserve the state of hooks between multiple calls to ``useState `` and
316+ ``useEffect `` calls.
317+
318+
319+ Only call hooks from IDOM functions
320+ -----------------------------------
321+
322+ **Don't call hooks from regular Python functions. ** Instead you should:
323+
324+ - ✅ Call Hooks from an element's render function.
325+
326+ - ✅ Call Hooks from another custom hook
327+
328+ Following this rule ensures stateful logic for IDOM element is always clearly
329+ separated from the rest of your codebase.
330+
331+
332+ Flake8 Plugin
333+ -------------
334+
335+ We provide a Flake8 plugin called `flake8-idom-hooks <Flake8 Linter Plugin >`_ that helps
336+ to enforce the two rules described above. You can ``pip `` install it directly, or with
337+ the ``lint `` extra for IDOM:
338+
339+ .. code-block :: bash
340+
341+ pip install idom[stable,lint]
342+
343+ Once installed running ``flake8 `` on your could will start catching errors:
344+
345+ .. code-block :: bash
346+
347+ flake8 my_idom_elements.py
348+
349+ .. code-block :: text
350+
351+ ./my_idom_elements:10:8 ROH102 hook 'use_effect' used inside if statement
352+ ./my_idom_elements:23:4 ROH102 hook 'use_state' used outside element or hook definition
311353
354+ See the Flake8 docs for
355+ `more info <https://flake8.pycqa.org/en/latest/user/configuration.html >`__.
312356
313357.. links
314358.. =====
315359
316360 .. _React Hooks : https://reactjs.org/docs/hooks-reference.html
317361.. _side effects : https://en.wikipedia.org/wiki/Side_effect_(computer_science)
318362.. _memoization : https://en.wikipedia.org/wiki/Memoization
319- .. _premature optimization : https://en.wikiquote.org/wiki/Donald_Knuth#Computer_Programming_as_an_Art_(1974)
320- .. _gh issues : https://github.com/idom-team/idom/issues
363+ .. _Flake8 Linter Plugin : https://github.com/idom-team/flake8-idom-hooks
0 commit comments