most react hooks updated
This commit is contained in:
parent
434bc6bfe5
commit
e002b7092c
@ -6,12 +6,13 @@ module.exports = {
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
'unused-imports',
|
||||
'react',
|
||||
'react-hooks',
|
||||
],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
@ -159,6 +160,9 @@ module.exports = {
|
||||
'react/jsx-props-no-multi-spaces': 'warn',
|
||||
'react/jsx-props-no-spreading': 'error',
|
||||
'react/jsx-tag-spacing': [ 'warn', { closingSlash: 'never', beforeSelfClosing: 'always', afterOpening: 'never', beforeClosing: 'never' } ],
|
||||
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -102,7 +102,7 @@ const DownloadButton: FC<DownloadButtonProps> = (props: DownloadButtonProps) =>
|
||||
|
||||
setButtonText('Reveal in Explorer');
|
||||
setDownloading(false);
|
||||
}, [ downloading, buttonShaking, downloadPath, downloadBuff ]);
|
||||
}, [ guild, resourceId, resourceName, downloading, buttonShaking, downloadPath, downloadBuff ]);
|
||||
|
||||
return <Button shaking={buttonShaking} onClick={downloadListener}>{buttonText}</Button>;
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ const ChoicesControl: FC<ChoicesControlProps> = (props: ChoicesControlProps) =>
|
||||
>
|
||||
{choice.display}
|
||||
</div>
|
||||
)), [ choices, selectedId ]);
|
||||
)), [ choices, selectedId, setSelectedId ]);
|
||||
|
||||
return (
|
||||
<div className="choices-react">
|
||||
|
@ -45,11 +45,11 @@ const Display: FC<DisplayProps> = (props: DisplayProps) => {
|
||||
}
|
||||
}, [ saving, saveFailed ]);
|
||||
|
||||
const dismissInfoMessage = () => {
|
||||
setDismissedInfoMessage(infoMessage);
|
||||
};
|
||||
|
||||
const popup = useMemo(() => {
|
||||
const dismissInfoMessage = () => {
|
||||
setDismissedInfoMessage(infoMessage);
|
||||
};
|
||||
|
||||
if (errorMessage) {
|
||||
return (
|
||||
<DisplayPopup tip={errorMessage}>
|
||||
@ -72,7 +72,7 @@ const Display: FC<DisplayProps> = (props: DisplayProps) => {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [ errorMessage, changes, resetChanges, saveChanges ]);
|
||||
}, [ errorMessage, infoMessage, dismissedInfoMessage, changes, resetChanges, saveChanges, saveButtonShaking, changesButtonText ]);
|
||||
|
||||
return (
|
||||
<div className="display">
|
||||
|
@ -30,7 +30,7 @@ const DropdownInput: FC<DropdownInputProps> = (props: DropdownInputProps) => {
|
||||
useEffect(() => {
|
||||
// only do this expensive version once
|
||||
setDisplay(options.find(option => option.value === value)?.display ?? '');
|
||||
}, []);
|
||||
}, [ options, value ]);
|
||||
|
||||
const optionElements = useMemo(() => options.map(option => {
|
||||
const className = option.value === value ? 'option selected' : 'option';
|
||||
@ -40,7 +40,7 @@ const DropdownInput: FC<DropdownInputProps> = (props: DropdownInputProps) => {
|
||||
setOptionsOpen(false);
|
||||
};
|
||||
return <div className={className} key={option.value} onClick={onClick}>{option.display}</div>;
|
||||
}), [ options ]);
|
||||
}), [ options, setValue, value ]);
|
||||
|
||||
const labelElement = useMemo(() => label && <div className="label">{label}</div>, [ label ]);
|
||||
|
||||
|
@ -40,7 +40,7 @@ const TextInput: FC<TextInputProps> = React.forwardRef(function TextInput(props:
|
||||
}
|
||||
setValid(true);
|
||||
setMessage(null);
|
||||
}, [ value ]);
|
||||
}, [ allowEmpty, label, maxLength, setMessage, setValid, value ]);
|
||||
|
||||
const labelElement = useMemo(() => label && <div className="label">{label}</div>, [ label ]);
|
||||
|
||||
|
@ -18,6 +18,8 @@ const Overlay: FC<OverlayProps> = (props: OverlayProps) => {
|
||||
const setOverlay = useSetRecoilState<ReactNode>(overlayState);
|
||||
|
||||
if (childRootRef) {
|
||||
// this is alright to do since childRootRef (the ref itself) should never change for each component using this element
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useActionWhenEscapeOrClickedOrContextOutsideEffect(childRootRef, () => setOverlay(null));
|
||||
}
|
||||
|
||||
|
@ -30,12 +30,12 @@ const ConnectionInfoContextMenu: FC<ConnectionInfoContextMenuProps> = (props: Co
|
||||
<div className="status-circle" />
|
||||
<div className="status-text">{status}</div>
|
||||
</div>
|
||||
)), [ setSelfStatus ]);
|
||||
)), [ setSelfStatus, close ]);
|
||||
|
||||
const openPersonalize = useCallback(() => {
|
||||
close();
|
||||
setOverlay(<PersonalizeOverlay guild={guild} selfMember={selfMember} />);
|
||||
}, [ close ]);
|
||||
}, [ close, guild, selfMember, setOverlay ]);
|
||||
|
||||
const alignment = useMemo(() => ({ bottom: 'top', centerX: 'centerX' }), []);
|
||||
|
||||
@ -54,3 +54,4 @@ const ConnectionInfoContextMenu: FC<ConnectionInfoContextMenuProps> = (props: Co
|
||||
};
|
||||
|
||||
export default ConnectionInfoContextMenu;
|
||||
|
||||
|
@ -32,12 +32,12 @@ const GuildTitleContextMenu: FC<GuildTitleContextMenuProps> = (props: GuildTitle
|
||||
return;
|
||||
}
|
||||
setOverlay(<GuildSettingsOverlay guild={guild} />);
|
||||
}, [ close ]);
|
||||
}, [ close, guild, setOverlay ]);
|
||||
|
||||
const openCreateChannel = useCallback(() => {
|
||||
close();
|
||||
setOverlay(<ChannelOverlay />);
|
||||
}, [ close ]);
|
||||
}, [ close, setOverlay ]);
|
||||
|
||||
const guildSettingsElement = useMemo(() => {
|
||||
if (!isLoaded(selfMember)) return null;
|
||||
@ -61,10 +61,11 @@ const GuildTitleContextMenu: FC<GuildTitleContextMenuProps> = (props: GuildTitle
|
||||
);
|
||||
}, [ selfMember, openCreateChannel ]);
|
||||
|
||||
if (guildSettingsElement === null && createChannelElement === null) return null;
|
||||
|
||||
const alignment = useMemo(() => ({ top: 'bottom', centerX: 'centerX' }), []);
|
||||
|
||||
if (guildSettingsElement === null && createChannelElement === null) return null;
|
||||
|
||||
return (
|
||||
<ContextMenu alignment={alignment} close={close} relativeToRef={relativeToRef} realignDeps={[ selfMember ]}>
|
||||
<div className="guild-title-context-menu">
|
||||
|
@ -43,14 +43,14 @@ const GuildOverviewDisplay: FC<GuildOverviewDisplayProps> = (props: GuildOvervie
|
||||
if (!isLoaded(guildMeta)) return;
|
||||
if (name === savedName) setName(guildMeta.value.name);
|
||||
setSavedName(guildMeta.value.name);
|
||||
}, [ guildMeta ]);
|
||||
}, [ guildMeta, name, savedName ]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoaded(iconResource)) {
|
||||
if (iconBuff === savedIconBuff) setIconBuff(iconResource.value.data);
|
||||
setSavedIconBuff(iconResource.value.data);
|
||||
}
|
||||
}, [ iconResource ]);
|
||||
}, [ iconBuff, iconResource, savedIconBuff ]);
|
||||
|
||||
const changes = useMemo(
|
||||
() => name !== savedName || iconBuff?.toString('hex') !== savedIconBuff?.toString('hex'),
|
||||
@ -110,7 +110,7 @@ const GuildOverviewDisplay: FC<GuildOverviewDisplayProps> = (props: GuildOvervie
|
||||
}
|
||||
|
||||
setSaving(false);
|
||||
}, [ name, iconBuff, errorMessage, saving, guild, iconBuff, savedIconBuff ]);
|
||||
}, [ name, iconBuff, errorMessage, saving, savedName, savedIconBuff, guild ]);
|
||||
|
||||
return (
|
||||
<Display
|
||||
|
@ -50,7 +50,7 @@ const ChannelElement: FC<ChannelElementProps> = (props: ChannelElementProps) =>
|
||||
|
||||
const launchModify = useCallback(() => {
|
||||
setOverlay(<ChannelOverlay channel={channel} />);
|
||||
}, [ guild, channel ]);
|
||||
}, [ setOverlay, channel ]);
|
||||
|
||||
return (
|
||||
<div className={baseClassName} onClick={setSelfActiveChannel}>
|
||||
|
@ -47,7 +47,7 @@ const MessageList: FC = () => {
|
||||
result.push(<MessageElement key={guild.id + 'm#' + message.id} guild={guild} message={message} prevMessage={prevMessage} />);
|
||||
}
|
||||
return result;
|
||||
}, [ messages ]);
|
||||
}, [ guild, messages ]);
|
||||
|
||||
return (
|
||||
<div className="message-list">
|
||||
|
@ -86,7 +86,7 @@ const AddGuildOverlay: FC<AddGuildOverlayProps> = (props: AddGuildOverlayProps)
|
||||
if (exampleAvatarBuff) {
|
||||
if (avatarBuff === null) setAvatarBuff(exampleAvatarBuff);
|
||||
}
|
||||
}, [ exampleAvatarBuff ]);
|
||||
}, [ avatarBuff, exampleAvatarBuff ]);
|
||||
|
||||
const validationErrorMessage = useMemo(() => {
|
||||
if (exampleAvatarBuffError && !avatarBuff) return 'Unable to load example avatar';
|
||||
|
@ -49,14 +49,14 @@ const ChannelOverlay: FC<ChannelOverlayProps> = (props: ChannelOverlayProps) =>
|
||||
} else {
|
||||
setEdited(name.length > 0 && flavorText.length > 0);
|
||||
}
|
||||
}, [ name, flavorText ]);
|
||||
}, [ name, flavorText, channel ]);
|
||||
|
||||
const validationErrorMessage = useMemo(() => {
|
||||
if (!edited) return null;
|
||||
if (!nameInputValid && nameInputMessage) return nameInputMessage;
|
||||
if (!flavorTextInputValid && flavorTextInputMessage) return flavorTextInputMessage;
|
||||
return null;
|
||||
}, [ nameInputValid, nameInputMessage, flavorTextInputValid, flavorTextInputMessage ]);
|
||||
}, [ edited, nameInputValid, nameInputMessage, flavorTextInputValid, flavorTextInputMessage ]);
|
||||
|
||||
const infoMessage = useMemo(() => {
|
||||
if (nameInputValid && nameInputMessage) return nameInputMessage;
|
||||
|
@ -48,11 +48,11 @@ const PersonalizeOverlay: FC<PersonalizeOverlayProps> = (props: PersonalizeOverl
|
||||
if (avatarBuff === savedAvatarBuff) setAvatarBuff(avatarResource.value.data);
|
||||
setSavedAvatarBuff(avatarResource.value.data);
|
||||
}
|
||||
}, [ avatarResource ]);
|
||||
}, [ avatarBuff, avatarResource, savedAvatarBuff ]);
|
||||
|
||||
useEffect(() => {
|
||||
displayNameInputRef.current?.focus();
|
||||
}, []);
|
||||
}, [ displayNameInputRef ]);
|
||||
|
||||
const validationErrorMessage = useMemo(() => {
|
||||
if (isFailed(avatarResource)) return 'Unable to load avatar';
|
||||
|
@ -109,7 +109,7 @@ const SendMessage: FC<SendMessageProps> = (props: SendMessageProps) => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
}, [ isMounted ]);
|
||||
|
||||
const removeAttachment = useCallback(() => {
|
||||
setAttachmentBuff(null);
|
||||
@ -121,7 +121,7 @@ const SendMessage: FC<SendMessageProps> = (props: SendMessageProps) => {
|
||||
const attachmentPreview = useMemo(() => {
|
||||
if (!attachmentBuff || !attachmentName) return null;
|
||||
return <AttachmentPreview attachmentBuff={attachmentBuff} attachmentName={attachmentName} remove={removeAttachment} />;
|
||||
}, [ attachmentBuff, attachmentName ]);
|
||||
}, [ attachmentBuff, attachmentName, removeAttachment ]);
|
||||
|
||||
// WARNING: The types on this are funky because of react's lack of explicit support for 'plaintext-only'
|
||||
const contentEditableType = useMemo(() => {
|
||||
|
Loading…
Reference in New Issue
Block a user