Skip to content

Commit

Permalink
Expose scoped versions of preact hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
DAreRodz committed Jan 12, 2024
1 parent 966f02d commit 3f34051
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 5 deletions.
12 changes: 10 additions & 2 deletions packages/interactivity/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ import { init } from './router';
export { store } from './store';
export { directive, getContext, getElement } from './hooks';
export { navigate, prefetch } from './router';
export { useWatch, useInit } from './utils';
export {
useWatch,
useInit,
useEffect,
useLayoutEffect,
useCallback,
useMemo,
} from './utils';

export { h as createElement, cloneElement } from 'preact';
export { useEffect, useLayoutEffect, useContext, useMemo } from 'preact/hooks';
export { useContext } from 'preact/hooks';
export { deepSignal } from 'deepsignal';

document.addEventListener( 'DOMContentLoaded', async () => {
Expand Down
79 changes: 76 additions & 3 deletions packages/interactivity/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/**
* External dependencies
*/
import { useEffect } from 'preact/hooks';
import {
useMemo as _useMemo,
useCallback as _useCallback,
useEffect as _useEffect,
useLayoutEffect as _useLayoutEffect,
} from 'preact/hooks';
import { effect } from '@preact/signals';

/**
Expand Down Expand Up @@ -43,7 +48,7 @@ function createFlusher( compute, notify ) {
// implementation comes from this PR, but we added short-cirtuiting to avoid
// infinite loops: https://github.com/preactjs/signals/pull/290
export function useSignalEffect( callback ) {
useEffect( () => {
_useEffect( () => {
let eff = null;
let isExecuting = false;
const notify = async () => {
Expand Down Expand Up @@ -102,7 +107,75 @@ export function useWatch( callback ) {
* @param {Function} callback The hook callback.
*/
export function useInit( callback ) {
useEffect( withScope( callback ), [] );
_useEffect( withScope( callback ), [] );
}

/**
* Accepts a function that contains imperative, possibly effectful code. The
* effects run after browser paint, without blocking it.
*
* This hook is equivalent to Preact's `useEffect` and makes the element's scope
* available so functions like `getElement()` and `getContext()` can be used
* inside the passed callback.
*
* @param {Function} callback Imperative function that can return a cleanup
* function.
* @param {any[]} inputs If present, effect will only activate if the
* values in the list change (using `===`).
*/
export function useEffect( callback, inputs ) {
_useEffect( withScope( callback ), inputs );
}

/**
* Accepts a function that contains imperative, possibly effectful code. Use
* this to read layout from the DOM and synchronously re-render.
*
* This hook is equivalent to Preact's `useLayoutEffect` and makes the element's
* scope available so functions like `getElement()` and `getContext()` can be
* used inside the passed callback.
*
* @param {Function} callback Imperative function that can return a cleanup
* function.
* @param {any[]} inputs If present, effect will only activate if the
* values in the list change (using `===`).
*/
export function useLayoutEffect( callback, inputs ) {
_useLayoutEffect( withScope( callback ), inputs );
}

/**
* Returns a memoized version of the callback that only changes if one of the
* inputs has changed (using `===`).
*
* This hook is equivalent to Preact's `useCallback` and makes the element's
* scope available so functions like `getElement()` and `getContext()` can be
* used inside the passed callback.
*
* @param {Function} callback Imperative function that can return a cleanup
* function.
* @param {any[]} inputs If present, effect will only activate if the
* values in the list change (using `===`).
*/
export function useCallback( callback, inputs ) {
_useCallback( withScope( callback ), inputs );
}

/**
* Pass a factory function and an array of inputs. `useMemo` will only recompute
* the memoized value when one of the inputs has changed.
*
* This hook is equivalent to Preact's `useMemo` and makes the element's scope
* available so functions like `getElement()` and `getContext()` can be used
* inside the passed factory function.
*
* @param {Function} factory Imperative function that can return a cleanup
* function.
* @param {any[]} inputs If present, effect will only activate if the
* values in the list change (using `===`).
*/
export function useMemo( factory, inputs ) {
_useMemo( withScope( factory ), inputs );
}

// For wrapperless hydration.
Expand Down

0 comments on commit 3f34051

Please sign in to comment.