Skip to content

RangeControl reset produces undefined but UI still displays previous numeric value (controlled state mismatch) #73456

@drill-lancer

Description

@drill-lancer

Description

When using RangeControl from @wordpress/components with allowReset={true}, the component behaves inconsistently when the current value is 0 and the block has been saved and reloaded.

Specifically:

  • After setting the value to 0 and saving the post, the block reloads with pcSize = 0 as the initial attribute value.

  • Pressing the Reset button correctly triggers onChange(undefined) and updates the block attribute to undefined using setAttributes.

  • However, the UI does not update:

    • The numeric input still displays 0.
    • The slider thumb remains at the 0 position.

This results in a mismatch between the actual stored value (undefined) and the UI’s displayed value (0), indicating that RangeControl does not properly behave as a fully controlled component when transitioning from a saved numeric value to undefined after a reset.

This issue only occurs after saving and reloading the block, suggesting that the problem is triggered when the initial value originates from saved post content rather than from editor-side state alone.

Step-by-step Reproduction Instructions

  1. Register a block using the code provided in the reproduction snippet, including a numeric attribute (e.g., pcSize).

  2. Insert the block into a post.

  3. Set the RangeControl value (PC size) to 0.

  4. Save the post.

  5. Reload the editor so the block is loaded from the saved post content.

    • At this point, the block attribute pcSize is initialized as 0 from saved markup.
  6. Open the browser console to observe the onChange output.

  7. Click the Reset button on the RangeControl.

  8. Observe the following behavior:

    • The console logs onChange -> undefined.
    • setAttributes({ pcSize: undefined }) updates the attribute as expected.
    • However, the UI still displays 0, and the slider thumb remains at the 0 position.
  9. Expected behavior:

    • After resetting to undefined, the UI should reflect an "unset" or blank state instead of keeping the previous 0 value.

Screenshots, screen recording, code snippet

block.json

{
  "apiVersion": 3,
  "name": "example/range-reset-bug",
  "title": "RangeControl Reset Bug",
  "category": "widgets",
  "attributes": {
    "pcSize": {
      "type": "number"
    }
  },
  "editorScript": "file:./index.js"
}

index.js

import { RangeControl } from '@wordpress/components';
import { useBlockProps } from '@wordpress/block-editor';

export default function Edit( { attributes, setAttributes } ) {
	const { pcSize } = attributes;

	const handleValueChange = ( value ) => {
		if ( value === '' || value === null || value === undefined ) {
			// Treat reset / empty as \"unset\" so the attribute is removed.
			console.log( 'onChange -> undefined' );
			setAttributes( { pcSize: undefined } );
		} else {
			const next = Number( value );
			console.log( 'onChange ->', next );
			setAttributes( { pcSize: next } );
		}
	};

	return (
		<div { ...useBlockProps() }>
			<RangeControl
				label="PC size"
				value={ pcSize }
				onChange={ handleValueChange }
				min={ 0 }
				max={ 100 }
				step={ 1 }
				allowReset={ true }
			/>
		</div>
	);
}

Environment info

  • @wordpress/components version: 30.8.0
  • @wordpress/scripts version: 31.0.0
  • WordPress version: 6.8.3
  • Browser: Chrome
  • OS: Windows 11 Pro 25H2

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Metadata

Metadata

Assignees

Labels

[Package] Components/packages/components[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions