Skip to content

Commit

Permalink
Memoize event handler creators
Browse files Browse the repository at this point in the history
  • Loading branch information
michaldudak committed Mar 19, 2024
1 parent 7629a9f commit e44c27d
Showing 1 changed file with 60 additions and 47 deletions.
107 changes: 60 additions & 47 deletions packages/mui-base/src/useSwitch/useSwitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,57 +38,70 @@ export function useSwitch(params: UseSwitchParameters): UseSwitchReturnValue {
state: 'checked',
});

const createHandleInputChange =
(otherProps: React.InputHTMLAttributes<HTMLInputElement>) =>
(event: React.ChangeEvent<HTMLInputElement>) => {
// Workaround for https://github.com/facebook/react/issues/9023
if (event.nativeEvent.defaultPrevented) {
return;
}
const createHandleButtonClick = React.useCallback(
(otherProps: React.ButtonHTMLAttributes<HTMLButtonElement>) =>
(event: React.MouseEvent<HTMLButtonElement>) => {
otherProps.onClick?.(event);
if (event.defaultPrevented || readOnly) {
return;
}

setCheckedState(event.target.checked);
onChange?.(event);
otherProps.onChange?.(event);
};
inputRef.current?.click();
},
[readOnly],
);

const createHandleClick =
(otherProps: React.ButtonHTMLAttributes<HTMLButtonElement>) =>
(event: React.MouseEvent<HTMLButtonElement>) => {
otherProps.onClick?.(event);
if (event.defaultPrevented || readOnly) {
return;
}
const getButtonProps: UseSwitchReturnValue['getButtonProps'] = React.useCallback(
(otherProps = {}) => ({
type: 'button',
role: 'switch',
'aria-checked': checked,
'aria-disabled': disabled,
'aria-readonly': readOnly,
...otherProps,
onClick: createHandleButtonClick(otherProps),
}),
[checked, disabled, readOnly, createHandleButtonClick],
);

inputRef.current?.click();
};
const createHandleInputChange = React.useCallback(
(otherProps: React.InputHTMLAttributes<HTMLInputElement>) =>
(event: React.ChangeEvent<HTMLInputElement>) => {
// Workaround for https://github.com/facebook/react/issues/9023
if (event.nativeEvent.defaultPrevented) {
return;
}

const getButtonProps: UseSwitchReturnValue['getButtonProps'] = (otherProps = {}) => ({
type: 'button',
role: 'switch',
'aria-checked': checked,
'aria-disabled': disabled,
'aria-readonly': readOnly,
...otherProps,
onClick: createHandleClick(otherProps),
});
setCheckedState(event.target.checked);
onChange?.(event);
otherProps.onChange?.(event);
},
[onChange, setCheckedState],
);

const getInputProps: UseSwitchReturnValue['getInputProps'] = (otherProps = {}) => ({
checked,
disabled,
name,
required,
style: visuallyHidden,
tabIndex: -1,
type: 'checkbox',
'aria-hidden': true,
...otherProps,
ref: handleInputRef,
onChange: createHandleInputChange(otherProps),
});
const getInputProps: UseSwitchReturnValue['getInputProps'] = React.useCallback(
(otherProps = {}) => ({
checked,
disabled,
name,
required,
style: visuallyHidden,
tabIndex: -1,
type: 'checkbox',
'aria-hidden': true,
...otherProps,
ref: handleInputRef,
onChange: createHandleInputChange(otherProps),
}),
[checked, disabled, name, required, createHandleInputChange, handleInputRef],
);

return {
checked,
getButtonProps,
getInputProps,
};
return React.useMemo(
() => ({
checked,
getButtonProps,
getInputProps,
}),
[checked, getButtonProps, getInputProps],
);
}

0 comments on commit e44c27d

Please sign in to comment.