From 02dde946dd51b0f89ca783d0c7bcdd7c66b043ec Mon Sep 17 00:00:00 2001 From: James Laver Date: Thu, 25 Apr 2019 14:33:42 +0200 Subject: [PATCH] expose R.Hooks.useRef --- README.md | 100 ++++++++++++++++++++++++++++++----------- src/Reactix/Hooks.js | 12 ++--- src/Reactix/Hooks.purs | 14 +++--- 3 files changed, 88 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index b31efbd..762c9fd 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,17 @@ -# purescript-reactix-lite +# purescript-reactix A minimal purescript binding to React Hooks ## Status: alpha -All hooks are implemented, few are tested well, if at all. +Features are being added and tested as I need them for work. + +Hooks believed to work correctly: + +* `useState` +* `useEffect` +* `useLayoutEffect` +* `useRef` ## Rationale @@ -28,37 +35,80 @@ Hooks are IMHO a breakthrough feature. They're simple to reason about and they're low on boilerplate. They make React programming much more fun and productive and I never want to touch a class component again. -## Concepts +Reactix is a Hooks-first (Hooks-only?) React library focusing on +simplicity and ease-of-use. -### Pure components + + + -### Hooks components +## Interop -## Limitations +If you wish to use this library with other react libraries, you will +need to write a little glue. The minimum you can sanely get away with +is a typed wrapper over `unsafeCoerce` between `Element` and whatever your +other library's element type is. ## Alternatives -This library uses React directly and knows nothing of any other -purescript React libraries. If you already use a react library, you -should consider one of these libraries instead: - -- [purescript-reactix-react](https://github.com/irresponsible/purescript-reactix-react) (a fork of this library to support purescript-react) -- [purescript-react-basic-hooks](https://github.com/spicydonuts/purescript-react-basic-hooks) (a similar library implemented on top of purescript-react-basic) - -# Gluing - -If you wish to use this library directly anyway, you will need to -write a little glue. - -# Usage - - - -# TODO - -More, better tests. +If you already use `purescript-react-basic`, you may prefer +[purescript-react-basic-hooks](https://github.com/spicydonuts/purescript-react-basic-hooks), +a similar library implemented on top of `purescript-react-basic`. + +## TODO + +* DOM + * safe props +* Synthetic Events + * Come up with a testing strategy + * What do do about event targets? + * Implement remaining +* React + * Refs + * isValid (test) + * context (createContext, provider, consumer, provide, consume) +* Hooks + * useEffect/useLayoutEffect + * Test they're fired at the correct stage + * useReducer + * Tests + * useMemo + * Tests + * useCallback + * Tests + * useRef + * Tests + * useContext + * Tests + * useImperativeHandle + * Tests + * useDebugValue + * Tests + +## Changelog + +### 0.1.1 + +* Add a, li, nav, ul tags to R.DOM.Raw +* Add `R.Hooks.useRef` + +### 0.1.0 + +* First numbered release +* Made `useState`, `useEffect` and `useLayoutEffect` take dummy + `Unit`s to delay execution until the appropriate time + +Supported Hooks: + +* `useState` +* `useEffect` +* `useLayoutEffect` + +Notable changes: + +* Major refactor to use [ffi-simple](https://github.com/irresponsible/purescript-ffi-simple). ## Copyright and License diff --git a/src/Reactix/Hooks.js b/src/Reactix/Hooks.js index 93cc54b..9763ec0 100644 --- a/src/Reactix/Hooks.js +++ b/src/Reactix/Hooks.js @@ -12,18 +12,14 @@ function _memo(prop) { } } exports._tuple = function tuple(ctor, v) { return ctor(v[0])(v[1]); }; - +exports._tupleCurrent = function tupleCurrent(ctor, ref) { + const set = function(v) { ref.current = v; }; + return ctor(ref.current)(set); +}; exports._useContext = _simple('useContext'); exports._useDebugValue = _simple('useDebugValue'); exports._useDebugValuePrime = _simple('useDebugValue'); // exports._useImperativeHandle = _simple('useImperativeHandle'); - -exports._useRef = function(ctor, value) { - const r = React.useRef(value); - const set = function(v) { r.current = v; }; - return ctor(r.current)(set); -}; - exports._useMemo = _simple('useMemo'); exports._useMemo1 = _memo('useMemo'); exports._useMemo2 = _memo('useMemo'); diff --git a/src/Reactix/Hooks.purs b/src/Reactix/Hooks.purs index fa1f802..3f40ca6 100644 --- a/src/Reactix/Hooks.purs +++ b/src/Reactix/Hooks.purs @@ -8,7 +8,7 @@ module Reactix.Hooks -- , useReducer, useReducer' -- , useContext -- , useMemo, useMemo1, useMemo2 --, useMemo3, useMemo4, useMemo5 - -- , Ref, useRef + , Ref, useRef -- , useDebugValue, useDebugValue' -- , useImperativeHandle ) @@ -143,12 +143,11 @@ useLayoutEffect5 a b c d f e = _useLayoutEffect e $ args5 a b c d f -- useRef -type Ref state = Tuple state (EffectFn1 state Unit) - -foreign import _useRef :: forall r s. EffectFn2 (r -> s -> Tuple r s) r (Ref r) +type Ref state = Tuple state (state -> Effect Unit) useRef :: forall r. r -> Hooks (Ref r) -useRef r = unsafeHooksEffect $ runEffectFn2 _useRef Tuple r +useRef r = hook $ \_ -> pure $ friendly $ tupleCurrent $ react ... "useRef" $ [ r ] + where friendly (Tuple v s) = Tuple v (runEffectFn1 s) -- useContext @@ -181,6 +180,11 @@ tuple = runFn2 _tuple Tuple foreign import _tuple :: forall a b c. Fn2 (a -> b -> Tuple a b) c (Tuple a b) +tupleCurrent :: forall a b c. a -> Tuple b c +tupleCurrent = runFn2 _tupleCurrent Tuple + +foreign import _tupleCurrent :: forall a b c. Fn2 (a -> b -> Tuple a b) c (Tuple a b) + hook :: forall v. (Unit -> Effect v) -> Hooks v hook = unsafeHooksEffect <<< delay