@@ -8,27 +8,38 @@ import { FieldWidgetProps } from './types';
88 */
99export function ObjectField ( { value, onChange, field, readonly, ...props } : FieldWidgetProps < any > ) {
1010 const config = field || ( props as any ) . schema ;
11- const [ jsonString , setJsonString ] = useState ( '' ) ;
11+
12+ // Initialize string state based on value
13+ const getInitialJsonString = ( ) => {
14+ if ( value === undefined || value === null ) return '' ;
15+ return JSON . stringify ( value , null , 2 ) ;
16+ } ;
17+
18+ const [ jsonString , setJsonString ] = useState ( getInitialJsonString ) ;
1219 const [ error , setError ] = useState < string | null > ( null ) ;
1320
14- // Initialize/Sync internal string state when value changes externally
21+ // Sync internal string state when value changes externally
22+ // This is a controlled component pattern where we need to sync external changes
1523 useEffect ( ( ) => {
1624 try {
17- if ( value === undefined || value === null ) {
18- setJsonString ( '' ) ;
19- return ;
20- }
21- // Only update if the parsed internal state doesn't match the new value
22- // This prevents cursor jumping/reformatting while typing valid JSON
23- const currentParsed = jsonString ? JSON . parse ( jsonString ) : null ;
24- if ( JSON . stringify ( currentParsed ) !== JSON . stringify ( value ) ) {
25- setJsonString ( JSON . stringify ( value , null , 2 ) ) ;
26- }
27- } catch ( e ) {
28- // Fallback if internal state was invalid JSON
25+ if ( value === undefined || value === null ) {
26+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Required for controlled component sync
27+ setJsonString ( '' ) ;
28+ return ;
29+ }
30+ // Only update if the parsed internal state doesn't match the new value
31+ // This prevents cursor jumping/reformatting while typing valid JSON
32+ const currentParsed = jsonString ? JSON . parse ( jsonString ) : null ;
33+ if ( JSON . stringify ( currentParsed ) !== JSON . stringify ( value ) ) {
34+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Required for controlled component sync
2935 setJsonString ( JSON . stringify ( value , null , 2 ) ) ;
36+ }
37+ } catch {
38+ // Fallback if internal state was invalid JSON
39+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Required for controlled component sync
40+ setJsonString ( JSON . stringify ( value , null , 2 ) ) ;
3041 }
31- } , [ value ] ) ;
42+ } , [ value , jsonString ] ) ;
3243
3344 if ( readonly ) {
3445 if ( ! value ) return < span className = "text-sm" > -</ span > ;
0 commit comments