From 94d39e5cc13eaf20c1cf52207adca6271bfc1e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rge=20N=C3=A6ss?= Date: Mon, 6 Jan 2025 13:31:14 +0100 Subject: [PATCH] fix(structure): set patchRef in an insertion effect instead of regular useEffect --- .../structure/panes/document/DocumentPaneProvider.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx index d35ec275dad3..29ed057106db 100644 --- a/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx +++ b/packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx @@ -10,7 +10,7 @@ import { import {useToast} from '@sanity/ui' import {fromString as pathFromString, pathFor, resolveKeyedPath} from '@sanity/util/paths' import {omit, throttle} from 'lodash' -import {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react' +import {memo, useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState} from 'react' import deepEquals from 'react-fast-compare' import { type DocumentFieldAction, @@ -297,10 +297,13 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => { const patchRef = useRef<(event: PatchEvent) => void>(() => { throw new Error( - 'Attempted to patch the Sanity document during initial render. Input components should only call `onChange()` in an effect or a callback.', + 'Attempted to patch the Sanity document during initial render or in an `useInsertionEffect`. Input components should only call `onChange()` in a useEffect or an event handler.', ) }) - useEffect(() => { + useInsertionEffect(() => { + // note: this needs to happen in an insertion effect to make sure we're ready to receive patches from child components when they run their effects initially + // in case they do e.g. `useEffect(() => props.onChange(set("foo")), [])` + // Note: although we discourage patch-on-mount, we still support it. patchRef.current = (event: PatchEvent) => { // when creating a new draft if (!editState.draft && !editState.published) {