diff --git a/services/web/frontend/js/features/binary-file/components/binary-file-header.js b/services/web/frontend/js/features/binary-file/components/binary-file-header.js index 8eeaf72d8f..d5b09c8fdc 100644 --- a/services/web/frontend/js/features/binary-file/components/binary-file-header.js +++ b/services/web/frontend/js/features/binary-file/components/binary-file-header.js @@ -1,10 +1,11 @@ -import React, { useState, useEffect, useRef, useCallback } from 'react' +import React, { useState, useCallback } from 'react' import PropTypes from 'prop-types' import Icon from '../../../shared/components/icon' import { formatTime, relativeDate } from '../../utils/format-date' import { Trans, useTranslation } from 'react-i18next' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' import { postJSON } from '../../../infrastructure/fetch-json' +import useIsMounted from '../../../shared/hooks/use-is-mounted' const tprLinkedFileInfo = importOverleafModules('tprLinkedFileInfo') const tprLinkedFileRefreshError = importOverleafModules( @@ -29,15 +30,11 @@ function shortenedUrl(url) { } export default function BinaryFileHeader({ file, storeReferencesKeys }) { - const isMounted = useRef(true) const [refreshing, setRefreshing] = useState(false) const [refreshError, setRefreshError] = useState(null) const { t } = useTranslation() - useEffect(() => { - // set to false on unmount to avoid unmounted component warning when refreshing - return () => (isMounted.current = false) - }, []) + const isMounted = useIsMounted() let fileInfo if (file.linkedFileData) { diff --git a/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js b/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js index 708bd60035..c51512cfbd 100644 --- a/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js +++ b/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useMemo, useRef } from 'react' +import React, { useState, useMemo } from 'react' import { useTranslation, Trans } from 'react-i18next' import { Form, FormGroup, FormControl, Button } from 'react-bootstrap' import { useMultipleSelection } from 'downshift' @@ -9,20 +9,12 @@ import { import SelectCollaborators from './select-collaborators' import { resendInvite, sendInvite } from '../utils/api' import { useUserContacts } from '../hooks/use-user-contacts' +import useIsMounted from '../../../shared/hooks/use-is-mounted' export default function AddCollaborators() { const [privileges, setPrivileges] = useState('readAndWrite') - const isMounted = useRef(true) - - // the component will be unmounted if the project can't have any more collaborators - useEffect(() => { - isMounted.current = true - - return () => { - isMounted.current = false - } - }, [isMounted]) + const isMounted = useIsMounted() const { data: contacts } = useUserContacts() diff --git a/services/web/frontend/js/shared/hooks/use-is-mounted.js b/services/web/frontend/js/shared/hooks/use-is-mounted.js new file mode 100644 index 0000000000..3fe667c3db --- /dev/null +++ b/services/web/frontend/js/shared/hooks/use-is-mounted.js @@ -0,0 +1,13 @@ +import { useEffect, useRef } from 'react' + +export default function useIsMounted() { + const isMounted = useRef(true) + + useEffect(() => { + return () => { + isMounted.current = false + } + }, [isMounted]) + + return isMounted +}