Update to latest eslint-plugin-react-hooks (#36702)

Co-authored-by: diondiondion <mail@diondiondion.com>
This commit is contained in:
Renaud Chaputanddiondiondion authored and GitHub committed 2025-11-10 14:50:04 +00:00
1 parent 4ddddc2573
commit 9addad8ce5
27 files changed
+382 -320

No files matched your search

@@ -47,7 +47,7 @@ export const AltTextBadge: React.FC<{ description: string }> = ({
rootClose
onHide={handleClose}
show={open}
target={anchorRef.current}
target={anchorRef}
placement='top-end'
flip
offset={offset}
@@ -76,6 +76,11 @@ export const Carousel = <
// Handle slide change
const [slideIndex, setSlideIndex] = useState(0);
const wrapperRef = useRef<HTMLDivElement>(null);
// Handle slide heights
const [currentSlideHeight, setCurrentSlideHeight] = useState(
() => wrapperRef.current?.scrollHeight ?? 0,
);
const previousSlideHeight = usePrevious(currentSlideHeight);
const handleSlideChange = useCallback(
(direction: number) => {
setSlideIndex((prev) => {
@@ -101,16 +106,11 @@ export const Carousel = <
[items.length, onChangeSlide],
);
// Handle slide heights
const [currentSlideHeight, setCurrentSlideHeight] = useState(
wrapperRef.current?.scrollHeight ?? 0,
);
const previousSlideHeight = usePrevious(currentSlideHeight);
const observerRef = useRef<ResizeObserver>(
new ResizeObserver(() => {
handleSlideChange(0);
}),
);
const observerRef = useRef<ResizeObserver | null>(null);
observerRef.current ??= new ResizeObserver(() => {
handleSlideChange(0);
});
const wrapperStyles = useSpring({
x: `-${slideIndex * 100}%`,
height: currentSlideHeight,
@@ -200,7 +200,7 @@ export const Carousel = <
};
type CarouselSlideWrapperProps<SlideProps extends CarouselSlideProps> = {
observer: ResizeObserver;
observer: ResizeObserver | null;
className: string;
active: boolean;
item: SlideProps;
@@ -217,7 +217,7 @@ const CarouselSlideWrapper = <SlideProps extends CarouselSlideProps>({
}: CarouselSlideWrapperProps<SlideProps>) => {
const handleRef = useCallback(
(instance: HTMLDivElement | null) => {
if (instance) {
if (observer && instance) {
observer.observe(instance);
}
},
@@ -1,4 +1,4 @@
import { useCallback, useState, useEffect, useRef } from 'react';
import { useCallback, useState, useRef } from 'react';
import { FormattedMessage } from 'react-intl';
@@ -12,11 +12,15 @@ export const ColumnSearchHeader: React.FC<{
const inputRef = useRef<HTMLInputElement>(null);
const [value, setValue] = useState('');
useEffect(() => {
// Reset the component when it turns from active to inactive.
// [More on this pattern](https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes)
const [previousActive, setPreviousActive] = useState(active);
if (active !== previousActive) {
setPreviousActive(active);
if (!active) {
setValue('');
}
}, [active]);
}
const handleChange = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => {
@@ -109,7 +109,7 @@ export const Dropdown: FC<
placement='bottom-start'
onHide={handleClose}
flip
target={buttonRef.current}
target={buttonRef}
popperConfig={{
strategy: 'fixed',
modifiers: [matchWidth],
@@ -27,22 +27,23 @@ export const ExitAnimationWrapper: React.FC<{
*/
children: (delayedIsActive: boolean) => React.ReactNode;
}> = ({ isActive = false, delayMs = 500, withEntryDelay, children }) => {
const [delayedIsActive, setDelayedIsActive] = useState(false);
const [delayedIsActive, setDelayedIsActive] = useState(
isActive && !withEntryDelay,
);
useEffect(() => {
if (isActive && !withEntryDelay) {
setDelayedIsActive(true);
const withDelay = !isActive || withEntryDelay;
return () => '';
} else {
const timeout = setTimeout(() => {
const timeout = setTimeout(
() => {
setDelayedIsActive(isActive);
}, delayMs);
},
withDelay ? delayMs : 0,
);
return () => {
clearTimeout(timeout);
};
}
return () => {
clearTimeout(timeout);
};
}, [isActive, delayMs, withEntryDelay]);
if (!isActive && !delayedIsActive) {
@@ -27,7 +27,6 @@ export const HoverCardController: React.FC = () => {
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout();
const [setScrollTimeout] = useTimeout();
const location = useLocation();
const handleClose = useCallback(() => {
cancelEnterTimeout();
@@ -36,9 +35,12 @@ export const HoverCardController: React.FC = () => {
setAnchor(null);
}, [cancelEnterTimeout, cancelLeaveTimeout, setOpen, setAnchor]);
useEffect(() => {
const location = useLocation();
const [previousLocation, setPreviousLocation] = useState(location);
if (location !== previousLocation) {
setPreviousLocation(location);
handleClose();
}, [handleClose, location]);
}
useEffect(() => {
let isScrolling = false;
@@ -1,4 +1,4 @@
import { useState, useEffect, useCallback, forwardRef } from 'react';
import { useCallback, forwardRef } from 'react';
import classNames from 'classnames';
@@ -55,23 +55,6 @@ export const IconButton = forwardRef<HTMLButtonElement, Props>(
},
buttonRef,
) => {
const [activate, setActivate] = useState(false);
const [deactivate, setDeactivate] = useState(false);
useEffect(() => {
if (!animate) {
return;
}
if (activate && !active) {
setActivate(false);
setDeactivate(true);
} else if (!activate && active) {
setActivate(true);
setDeactivate(false);
}
}, [setActivate, setDeactivate, animate, active, activate]);
const handleClick: React.MouseEventHandler<HTMLButtonElement> = useCallback(
(e) => {
e.preventDefault();
@@ -112,8 +95,8 @@ export const IconButton = forwardRef<HTMLButtonElement, Props>(
active,
disabled,
inverted,
activate,
deactivate,
activate: animate && active,
deactivate: animate && !active,
overlayed: overlay,
'icon-button--with-counter': typeof counter !== 'undefined',
});
+4 -2
View File
@@ -35,6 +35,9 @@ const messages = defineMessages({
},
});
const isPollExpired = (expiresAt: Model.Poll['expires_at']) =>
new Date(expiresAt).getTime() < Date.now();
interface PollProps {
pollId: string;
status: Status;
@@ -58,8 +61,7 @@ export const Poll: React.FC<PollProps> = ({ pollId, disabled, status }) => {
if (!poll) {
return false;
}
const expiresAt = poll.expires_at;
return poll.expired || new Date(expiresAt).getTime() < Date.now();
return poll.expired || isPollExpired(poll.expires_at);
}, [poll]);
const timeRemaining = useMemo(() => {
if (!poll) {
@@ -44,6 +44,7 @@ export const RemoveQuoteHint: React.FC<{
if (!firstHintId) {
firstHintId = uniqueId;
// eslint-disable-next-line react-hooks/set-state-in-effect
setIsOnlyHint(true);
}
@@ -64,8 +65,8 @@ export const RemoveQuoteHint: React.FC<{
flip
offset={[12, 10]}
placement='bottom-end'
target={anchorRef.current}
container={anchorRef.current}
target={anchorRef}
container={anchorRef}
>
{({ props, placement }) => (
<div