Skip to content

Commit d13dfd0

Browse files
committed
Fix Switch state sync when used inside a Portal
1 parent ff0df54 commit d13dfd0

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/components/Switch/Switch.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,33 @@ const Switch = ({
6767
...rest
6868
}: Props) => {
6969
const theme = useInternalTheme(themeOverrides);
70+
71+
// Internal state is needed to fix #4789 where Switch is inside a Portal
72+
const [internalValue, setInternalValue] = React.useState<boolean>(() =>
73+
typeof value === 'boolean' ? value : false
74+
);
75+
76+
React.useEffect(() => {
77+
if (typeof value === 'boolean' && value !== internalValue) {
78+
setInternalValue(value);
79+
}
80+
}, [value, internalValue]);
81+
7082
const { checkedColor, onTintColor, thumbTintColor } = getSwitchColor({
7183
theme,
7284
disabled,
73-
value,
85+
value: internalValue,
7486
color,
7587
});
7688

89+
const handleValueChange = React.useCallback(
90+
(newValue: boolean) => {
91+
setInternalValue(newValue);
92+
onValueChange?.(newValue);
93+
},
94+
[onValueChange]
95+
);
96+
7797
const props =
7898
version && version.major === 0 && version.minor <= 56
7999
? {
@@ -96,13 +116,15 @@ const Switch = ({
96116

97117
return (
98118
<NativeSwitch
99-
value={value}
119+
value={internalValue}
100120
disabled={disabled}
101-
onValueChange={disabled ? undefined : onValueChange}
121+
onValueChange={disabled ? undefined : handleValueChange}
102122
{...props}
103123
{...rest}
104124
/>
105125
);
106126
};
107127

128+
Switch.displayName = 'Switch';
129+
108130
export default Switch;

0 commit comments

Comments
 (0)