Add an ESLint rule to prevent the usage of useRef other than for HTML elements. (#2014)

* Add an ESLint rule to prevent the usage of useRef other than for HTML elements

Co-authored-by: v1b3m <vibenjamin6@gmail.com>

* Bump eslint version and rewrite rule

* Fix

---------

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
gitstart-twenty
2023-10-14 12:32:46 +03:00
committed by GitHub
parent 258685467b
commit 0c79217ba0
36 changed files with 248 additions and 943 deletions

View File

@ -13,6 +13,7 @@ import { useUpdateEffect } from '~/hooks/useUpdateEffect';
import { ApolloFactory } from '../services/apollo.factory';
export const useApolloFactory = () => {
// eslint-disable-next-line twenty/no-state-useref
const apolloRef = useRef<ApolloFactory<NormalizedCacheObject> | null>(null);
const [isDebugMode] = useRecoilState(isDebugModeState);

View File

@ -50,7 +50,7 @@ export const DateInput = ({
const [internalValue, setInternalValue] = useState(value);
const wrapperRef = useRef(null);
const wrapperRef = useRef<HTMLDivElement>(null);
const { refs, floatingStyles } = useFloating({
placement: 'bottom-start',

View File

@ -64,7 +64,7 @@ export const PhoneInput = ({
}: PhoneInputProps) => {
const [internalValue, setInternalValue] = useState<string | undefined>(value);
const wrapperRef = useRef<HTMLDivElement | null>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
useEffect(() => {
setInternalValue(value);

View File

@ -36,7 +36,7 @@ export const TextInput = ({
}: TextInputProps) => {
const [internalText, setInternalText] = useState(value);
const wrapperRef = useRef(null);
const wrapperRef = useRef<HTMLInputElement>(null);
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setInternalText(event.target.value);

View File

@ -49,7 +49,9 @@ export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
const theme = useTheme();
const controls = useAnimation();
// eslint-disable-next-line twenty/no-state-useref
const startTimestamp = useRef<number>(0);
// eslint-disable-next-line twenty/no-state-useref
const remainingTime = useRef<number>(duration);
const start = useCallback(async () => {

View File

@ -116,6 +116,7 @@ export const SnackBar = ({
}: SnackBarProps) => {
const theme = useTheme();
// eslint-disable-next-line twenty/no-state-useref
const progressBarRef = useRef<ProgressBarControls | null>(null);
const closeSnackbar = useCallback(() => {

View File

@ -1,9 +1,13 @@
import { useCallback, useEffect, useRef } from 'react';
export const usePausableTimeout = (callback: () => void, delay: number) => {
// eslint-disable-next-line twenty/no-state-useref
const savedCallback = useRef<() => void>(callback);
// eslint-disable-next-line twenty/no-state-useref
const remainingTime = useRef<number>(delay);
// eslint-disable-next-line twenty/no-state-useref
const startTime = useRef<number>(Date.now());
// eslint-disable-next-line twenty/no-state-useref
const timeoutId = useRef<ReturnType<typeof setTimeout> | null>(null);
const tick = () => {

View File

@ -54,7 +54,7 @@ export const BoardColumnMenu = ({
const [currentMenu, setCurrentMenu] = useState('actions');
const column = useContext(BoardColumnContext);
const boardColumnMenuRef = useRef(null);
const boardColumnMenuRef = useRef<HTMLDivElement>(null);
const { enqueueSnackBar } = useSnackBar();
const createCompanyProgress = useCreateCompanyProgress();

View File

@ -28,7 +28,7 @@ export const DropdownMenuContainer = ({
onClose,
width,
}: DropdownMenuContainerProps) => {
const dropdownRef = useRef(null);
const dropdownRef = useRef<HTMLDivElement>(null);
useListenClickOutside({
refs: [dropdownRef],

View File

@ -51,7 +51,7 @@ export const RightDrawer = () => {
const { closeRightDrawer } = useRightDrawer();
const rightDrawerRef = useRef(null);
const rightDrawerRef = useRef<HTMLDivElement>(null);
useListenClickOutside({
refs: [rightDrawerRef],

View File

@ -37,7 +37,7 @@ export const ActionBar = ({ selectedIds }: ActionBarProps) => {
const actionBarOpen = useRecoilValue(actionBarOpenState);
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
const actionBarEntries = useRecoilValue(actionBarEntriesState);
const wrapperRef = useRef(null);
const wrapperRef = useRef<HTMLDivElement>(null);
if (selectedIds.length === 0 || !actionBarOpen || contextMenuIsOpen) {
return null;

View File

@ -47,7 +47,7 @@ export const ContextMenu = ({ selectedIds }: ContextMenuProps) => {
const contextMenuEntries = useRecoilValue(contextMenuEntriesState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
const wrapperRef = useRef(null);
const wrapperRef = useRef<HTMLDivElement>(null);
useListenClickOutside({
refs: [wrapperRef],

View File

@ -6,8 +6,8 @@ import { useListenClickOutside } from '../useListenClickOutside';
const onOutsideClick = jest.fn();
const TestComponentDomMode = () => {
const buttonRef = useRef(null);
const buttonRef2 = useRef(null);
const buttonRef = useRef<HTMLButtonElement>(null);
const buttonRef2 = useRef<HTMLButtonElement>(null);
useListenClickOutside({
refs: [buttonRef, buttonRef2],
callback: onOutsideClick,

View File

@ -18,6 +18,7 @@ export const RecoilScope = ({
scopeId?: string;
CustomRecoilScopeContext?: RecoilScopeContextType;
}) => {
// eslint-disable-next-line twenty/no-state-useref
const currentScopeId = useRef(scopeId ?? v4());
return CustomRecoilScopeContext ? (