Skip to content

Commit

Permalink
Allow dependencies to be passed to useComputed
Browse files Browse the repository at this point in the history
  • Loading branch information
clauderic committed Sep 17, 2024
1 parent 0a1826e commit ff17c04
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/use-computed-deps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@dnd-kit/react': patch
---

Allow dependencies to be passed to `useComputed` hook.
5 changes: 2 additions & 3 deletions packages/react/src/core/hooks/useDragOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import {useDragDropManager} from './useDragDropManager.ts';

export function useDragOperation() {
const manager = useDragDropManager();

const source = useComputed(() => manager?.dragOperation.source);
const target = useComputed(() => manager?.dragOperation.target);
const source = useComputed(() => manager?.dragOperation.source, [manager]);
const target = useComputed(() => manager?.dragOperation.target, [manager]);

return {
get source() {
Expand Down
13 changes: 10 additions & 3 deletions packages/react/src/hooks/useComputed.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import {useMemo, useRef} from 'react';
import {computed} from '@dnd-kit/state';

import {useConstant} from './useConstant.ts';
import {useSignal} from './useSignal.ts';

export function useComputed<T = any>(compute: () => T, sync = false) {
export function useComputed<T = any>(
compute: () => T,
dependencies: any[] = [],
sync = false
) {
const $compute = useRef(compute);
$compute.current = compute;

return useSignal(
useConstant(() => computed(compute)),
useMemo(() => computed(() => $compute.current()), dependencies),
sync
);
}
17 changes: 7 additions & 10 deletions packages/react/src/hooks/useSignal.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
import {useState} from 'react';
import {flushSync} from 'react-dom';
import {effect, signal, Signal} from '@dnd-kit/state';
import {effect, Signal} from '@dnd-kit/state';

import {useConstant} from './useConstant.ts';
import {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect.ts';

/** Wrap the given value in a Signal if it isn't already one, and make changes trigger a re-render. */
export function useSignal<T = any>(signalOrValue: T, sync = false) {
const sig = useConstant(() =>
signalOrValue instanceof Signal ? signalOrValue : signal(signalOrValue)
) as T extends Signal ? T : Signal<T>;
let val = sig.peek();
export function useSignal<T = any>(signal: Signal<T>, sync = false) {
let val = signal.peek();
const update = useState(val)[1];

useIsomorphicLayoutEffect(
() =>
effect(() => {
if (val !== (val = sig.value)) {
if (val !== (val = signal.value)) {
if (sync) {
flushSync(() => update(val));
} else {
update(val);
}
}
}),
[sync]
[signal, sync]
);
return sig;

return signal;
}

0 comments on commit ff17c04

Please sign in to comment.