Schema update after `onChange` is dropped when the new schema adds a property with a default
Prerequisites
- I have searched the existing issues
- I understand that providing a SSCCE example is tremendously useful to the maintainers.
- I have read the documentation
- Ideally, I'm providing a sample JSFiddle, Codesandbox.io or preferably a shared playground link demonstrating the issue.
What theme are you using?
core
Version
6.10.1
Current Behavior
When the parent component derives the schema from the current formData, the schema update that follows an onChange is silently dropped. The new field never renders, and there is no error or warning.
This only happens when the property that the new schema adds has a default. Remove the default and the same update is applied correctly. Any field type is affected.
Expected Behavior
A schema prop change should always be applied, whether or not the new schema adds a property with a default.
Steps To Reproduce
Open the sandbox, or run this component:
import { useState } from 'react';
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
const getSchema = (formData) => ({
type: 'object',
properties: {
trigger: { type: 'string', title: 'Trigger' },
...(formData?.trigger === 'show'
? {
extra: {
type: 'string',
title: 'Extra',
default: 'preset', // remove this line and the bug goes away
},
}
: {}),
},
});
export default function App() {
const [formData, setFormData] = useState({});
return (
<Form
schema={getSchema(formData)}
validator={validator}
formData={formData}
onChange={(event) => setFormData(event.formData)}
/>
);
}- Type
showinto theTriggerfield. - Expected: a second field,
Extra, appears, pre-filled withpreset. - Actual: nothing appears. Only
Triggeris rendered. - Delete the
default: 'preset'line and repeat.Extranow appears as expected.
liveValidate makes no difference; I tested with and without it.
Environment
- OS: macOS 27.0
- Node: 24.18.1
- npm: 11.16.0
- React: 19.2.8Anything else?
The cause looks like a flag that is set but not always cleared. processPendingChange() sets isProcessingUserChange = true. The setState it makes commits with unchanged props, so getSnapshotBeforeUpdate returns { shouldUpdate: false } and componentDidUpdate never reaches the line that clears the flag, because that line sits inside the if (snapshot.shouldUpdate) block. The parent's reply to onChange then arrives with the stale flag still set. The default in the new schema is what makes nextState.formData differ from props.formData, so the guard fires and the computed state is thrown away
Source: rjsf-team/react-jsonschema-form