Skip to content

Commit

Permalink
renaming + order + README props per function
Browse files Browse the repository at this point in the history
  • Loading branch information
Yair Even Or authored and Yair Even Or committed Jul 20, 2022
1 parent afa4066 commit ab3939f
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 31 deletions.
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ npm i @yaireo/\useSmartRef -S

### `useWatchableRef`

| Argument | Type | Info
|---------------|-------|-------------------------------------------------------------
| initialValue | Any | Same as the native `useRef`

Create a ref-like object that listens to any change in the `current` property
and fires all registered callbacks when a change happens to the `current` property.

Expand All @@ -43,30 +47,41 @@ const Component = () => {
}
```

### `useWatchable`
### `useWatchableListener`

| Argument | Type | Info
|----------|----------|-------------------------------------------------------------
| ref | Object | an Object/Array to listen to
| propName | String | (optional) specific property name to watch within the `ref`
| watcher | function | (optional) argument, for custom watcher

Listens to refs changes.
By default will trigger a re-render in the component which is using this hook if
a change in the ref itself or specific property is detected.

```js
import {useSmartRef} from '@yaireo/react-ref-watcher'
import {useWatchableListener} from '@yaireo/react-ref-watcher'

const Component = ({ ref1 }) => {
const {ref2} = useContext(MyContext) // getting a ref from somewhere up the tree

useWatchable(ref1) // triggers a re-render when ref1 changes (assuming the `ref1.current` is pointing now a new pointer in memory)
useWatchable(ref2.current, 'foo') // triggers a re-render when `foo` property changes in ref2.current (assuming ref2.current is an Object)
useWatchableListener(ref1) // triggers a re-render when ref1 changes (assuming the `ref1.current` is pointing now a new pointer in memory)
useWatchableListener(ref2.current, 'foo') // triggers a re-render when `foo` property changes in ref2.current (assuming ref2.current is an Object)
}
```


### `useWatchableEffect`

| Argument | Type | Info
|---------------|----------|-------------------------------------------------------------
| callback | Function | fires when a ref change detetced
| dependencies | Array | array of watchable "smart" refs

Listen to changes in a ref **without** triggering a re-render

```js
import {useSmartRef} from '@yaireo/react-ref-watcher'
import {useWatchableEffect, useSmartRefListener} from '@yaireo/react-ref-watcher'

const Component = ({ ref1, ref2 }) => {
useWatchableEffect(() => {
Expand All @@ -91,6 +106,8 @@ callback functions defined in the `__WATCHERS` property will fire.
**Example of most basic usage:**

```js
import {propWatcher} from '@yaireo/react-ref-watcher'

const watchableRef = propWatcher({ current: true })
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"files": [
"src/index.js",
"src/useWatchableRef.js",
"src/useWatchable.js",
"src/useWatchableListener.js",
"src/useWatchableEffect.js",
"src/propWatcher.js"
],
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export {default as useWatchableRef} from './useWatchableRef'
export {default as useWatchable} from './useWatchable'
export {default as useWatchableListener} from './useWatchableListener'
export {default as useWatchableEffect} from './useWatchableEffect'
export {default as propWatcher} from './propWatcher'
28 changes: 15 additions & 13 deletions src/useWatchableEffect.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@ import {useId} from 'react'
* @param {*} callback fires when a ref change detetced
* @param {*} dependencies array of watchable "smart" refs
*/
export const useWatchableEffect = (callback, dependencies) => {
const useWatchableEffect = (callback, dependencies) => {
const id = useId()

dependencies.forEach(ref => {
// catch errors
if( !ref ) {
console.warn("useWatchableEffect - ref does not exists")
return
}
// catch errors
if( !ref ) {
console.warn("useWatchableEffect - ref does not exists")
return
}

if( !ref.__WATCHERS ) {
console.warn("useWatchableEffect - ref is not watchable. Did you pass the correct Object?")
return
}
if( !ref.__WATCHERS ) {
console.warn("useWatchableEffect - ref is not watchable. Did you pass the correct Object?")
return
}

// register a listener for that namespace
ref.__WATCHERS[id] = callback
// register a listener for that namespace
ref.__WATCHERS[id] = callback
})
}
}

export default useWatchableEffect;
19 changes: 9 additions & 10 deletions src/useWatchable.js → src/useWatchableListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ import {useId, useState, useCallback} from 'react'
* Listens to refs changes.
* By default will trigger a re-render in the component which is using this hook if
* a change in the ref itself or specific property is detected.
* @param {*} ref an object to listen to
* @param {*} path (optional) path
* @param {Object} ref an object to listen to
* @param {String} propName (optional) specific property name to watch within the `ref`
* @param {function} watcher (optional) the logic which decides if the component should be re-rendered
*/
const useWatchable = (
const useWatchableListener = (
ref,
propName,

// optional argument, for custom watcher
watcher = (propName, prop, value, setState) =>
prop === propName // if "propName" is not defined, listen to all changes at any prop
? setState(value)
: !propName && setState(Math.random()) // if no "propName" supplied, assume any change to any prop should be watched, hence the value is not important and to trigger a re-render a new state must be uniquly generated
? setState(value)
: !propName && setState(Math.random()) // if no "propName" supplied, assume any change to any prop should be watched, hence the value is not important and to trigger a re-render a new state must be uniquly generated
) => {

const [state, setState] = useState()
Expand All @@ -25,12 +24,12 @@ const useWatchable = (

// catch errors
if( !ref ) {
console.warn("useWatchable - ref does not exists")
console.warn("useWatchableListener - ref does not exists")
return
}

if( !ref.__WATCHERS ) {
console.warn("useWatchable - ref is not watchable. Did you pass the correct Object?")
console.warn("useWatchableListener - ref is not watchable. Did you pass the correct Object?")
return
}

Expand All @@ -40,4 +39,4 @@ const useWatchable = (
return unlisten
}

export default useWatchable
export default useWatchableListener
2 changes: 1 addition & 1 deletion src/useWatchableRef.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import propWatcher from './propWatcher'
* Create a ref-like object that listens to any change in the "current" property
* and fires all registered callbacks when a change happens to the "current" property.
*/
const useSmartRef = (initialValue) => useMemo(() => propWatcher({ current: initialValue }), [])
const useWatchableRef = (initialValue) => useMemo(() => propWatcher({ current: initialValue }), [])

export default useWatchableRef

0 comments on commit ab3939f

Please sign in to comment.