Change:
Following up on (/cc ) React version: 18.0.0-rc.3-next-- an update (e.g. ) from within Link to code example: Update is applied and no warning is issued. According to cannot schedule updates. But seems to "work". Maybe this is just incidental because it's the first render? I got the impression that this should definitely cause a warning (not implemented) but I wonder if we also should consistently drop updates from ?

Discussion:
restorePendingUpdaters, addTransitionStartCallbackToPendingTransition, addTransitionCompleteCallbackToPendingTransition, <ins> setIsRunningInsertionEffect, </ins> } from './ReactFiberWorkLoop.new'; import { NoFlags as NoHookEffect,

restorePendingUpdaters, addTransitionStartCallbackToPendingTransition, addTransitionCompleteCallbackToPendingTransition, <ins> setIsRunningInsertionEffect, </ins> } from './ReactFiberWorkLoop.old'; import { NoFlags as NoHookEffect,

} } <ins> if (__DEV__) { if ((flags & HookInsertion) !== NoHookEffect) { setIsRunningInsertionEffect(true); } } </ins> safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); <ins> if (__DEV__) { if ((flags & HookInsertion) !== NoHookEffect) { setIsRunningInsertionEffect(false); } } </ins> if (enableSchedulingProfiler) { if ((flags & HookPassive) !== NoHookEffect) {

// Mount const create = effect.create; <ins> if (__DEV__) { if ((flags & HookInsertion) !== NoHookEffect) { setIsRunningInsertionEffect(true); } } </ins> effect.destroy = create(); <ins> if (__DEV__) { if ((flags & HookInsertion) !== NoHookEffect) { setIsRunningInsertionEffect(false); } } </ins> if (enableSchedulingProfiler) { if ((flags & HookPassive) !== NoHookEffect) {

let currentEventTime: number = NoTimestamp; let currentEventTransitionLane: Lanes = NoLanes; <ins> let isRunningInsertionEffect = false; </ins> export function getWorkInProgressRoot(): FiberRoot | null { return workInProgressRoot; }

): FiberRoot | null { checkForNestedUpdates(); <ins> if (__DEV__) { if (isRunningInsertionEffect) { console.error('useInsertionEffect must not schedule updates.'); } } </ins> const root = markUpdateLaneFromFiberToRoot(fiber, lane); if (root === null) { return null;

nearestMountedAncestor: Fiber | null, error: mixed, ) { <ins> if (__DEV__) { setIsRunningInsertionEffect(false); } </ins> if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it.

} } } <ins> export function setIsRunningInsertionEffect(isRunning: boolean): void { if (__DEV__) { isRunningInsertionEffect = isRunning; } } </ins>

}), ).toThrow('is not a function'); }); <ins> it('warns when setState is called from insertion effect setup', () => { function App(props) { const [, setX] = useState(0); useInsertionEffect(() => { setX(1); if (props.throw) { throw Error('No'); } }, [props.throw]); return null; } const root = ReactNoop.createRoot(); expect(() => act(() => { root.render(<App />); }), ).toErrorDev(['Warning: useInsertionEffect must not schedule updates.']); expect(() => { act(() => { root.render(<App throw={true} />); }); }).toThrow('No'); // Should not warn for regular effects after throw. function NotInsertion() { const [, setX] = useState(0); useEffect(() => { setX(1); }, []); return null; } act(() => { root.render(<NotInsertion />); }); }); it('warns when setState is called from insertion effect cleanup', () => { function App(props) { const [, setX] = useState(0); useInsertionEffect(() => { if (props.throw) { throw Error('No'); } return () => { setX(1); }; }, [props.throw, props.foo]); return null; } const root = ReactNoop.createRoot(); act(() => { root.render(<App foo="hello" />); }); expect(() => { act(() => { root.render(<App foo="goodbye" />); }); }).toErrorDev(['Warning: useInsertionEffect must not schedule updates.']); expect(() => { act(() => { root.render(<App throw={true} />); }); }).toThrow('No'); // Should not warn for regular effects after throw. function NotInsertion() { const [, setX] = useState(0); useEffect(() => { setX(1); }, []); return null; } act(() => { root.render(<NotInsertion />); }); }); </ins> }); describe('useLayoutEffect', () => {