diff --git a/src/components/Switch/Switch.tsx b/src/components/Switch/Switch.tsx index 04b0fef0c6..63453391ae 100644 --- a/src/components/Switch/Switch.tsx +++ b/src/components/Switch/Switch.tsx @@ -67,13 +67,33 @@ const Switch = ({ ...rest }: Props) => { const theme = useInternalTheme(themeOverrides); + + // Internal state is needed to fix #4789 where Switch is inside a Portal + const [internalValue, setInternalValue] = React.useState(() => + typeof value === 'boolean' ? value : false + ); + + React.useEffect(() => { + if (typeof value === 'boolean' && value !== internalValue) { + setInternalValue(value); + } + }, [value, internalValue]); + const { checkedColor, onTintColor, thumbTintColor } = getSwitchColor({ theme, disabled, - value, + value: internalValue, color, }); + const handleValueChange = React.useCallback( + (newValue: boolean) => { + setInternalValue(newValue); + onValueChange?.(newValue); + }, + [onValueChange] + ); + const props = version && version.major === 0 && version.minor <= 56 ? { @@ -96,13 +116,15 @@ const Switch = ({ return ( ); }; +Switch.displayName = 'Switch'; + export default Switch;