diff --git a/.changeset/tasty-cooks-own.md b/.changeset/tasty-cooks-own.md new file mode 100644 index 000000000..b2fca7f10 --- /dev/null +++ b/.changeset/tasty-cooks-own.md @@ -0,0 +1,5 @@ +--- +"@preact/signals": patch +--- + +Allow for context to propagate to components using context diff --git a/packages/preact/src/index.ts b/packages/preact/src/index.ts index 5171394ae..f2968c0c5 100644 --- a/packages/preact/src/index.ts +++ b/packages/preact/src/index.ts @@ -271,7 +271,7 @@ hook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => { /** Mark components that use hook state so we can skip sCU optimization. */ hook(OptionsTypes.HOOK, (old, component, index, type) => { - if (type < 3) + if (type < 3 || type === 9) (component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE; old(component, index, type); }); diff --git a/packages/preact/test/index.test.tsx b/packages/preact/test/index.test.tsx index 212375da1..9bc5bb11d 100644 --- a/packages/preact/test/index.test.tsx +++ b/packages/preact/test/index.test.tsx @@ -1,11 +1,12 @@ import { - signal, computed, useComputed, useSignalEffect, Signal, + signal, } from "@preact/signals"; -import { createElement, createRef, render } from "preact"; +import { createElement, createRef, render, createContext } from "preact"; +import { useContext, useState } from "preact/hooks"; import { setupRerender, act } from "preact/test-utils"; const sleep = (ms?: number) => new Promise(r => setTimeout(r, ms)); @@ -417,6 +418,39 @@ describe("@preact/signals", () => { }); }); + describe('hooks mixed with signals', () => { + it('signals should not stop context from propagating', () => { + const ctx = createContext({ test: 'should-not-exist' }); + let update: any; + + function Provider(props: any) { + const [test, setTest] = useState('foo'); + update = setTest + return ( + {props.children} + ); + } + + const s = signal('baz') + function Test() { + const value = useContext(ctx); + return

{value.test} {s.value}

+ } + + function App() { + return + } + + render(, scratch); + + expect(scratch.innerHTML).to.equal('

foo baz

') + act(() => { + update('bar') + }) + expect(scratch.innerHTML).to.equal('

bar baz

') + }) + }) + describe("useSignalEffect()", () => { it("should be invoked after commit", async () => { const ref = createRef();