J'ai le composant suivant qui affiche un lien cliquable pour le téléchargement de fichiers
import { gql, useLazyQuery, useMutation } from '@apollo/client'; import { useEffect, useState } from 'react'; import type FileUpload from '@app/data/models/FileUpload'; import { ExternalLink } from '@app/mcui/components/atoms/business-process/shared/ExternalLink'; import { isNonEmptyString } from '@divvy-homes/utils'; export type Props = { uploadId: FileUpload['id']; }; const FILE_UPLOAD_QUERY = gql` query ($id: UUID!) { getFileUpload(id: $id) { id fileName url } } `; const SIGN_FILE_MUTATION = gql` mutation ($url: String!) { signAdminUploadUrl(url: $url) } `; export const FileUploadLink = ({ uploadId }: Props) => { const [fileUrl, setFileUrl] = useState<string>(); const [fileName, setFileName] = useState<string>(); const [getFileData] = useLazyQuery<{ getFileUpload: { url: string; fileName: string; }; }>(FILE_UPLOAD_QUERY, { onError: console.error, onCompleted: (data) => { setFileName(data.getFileUpload.fileName); setFileUrl(data.getFileUpload.url); }, variables: { id: uploadId, }, }); useEffect(() => { void getFileData({ variables: { uploadId } }); }, [getFileData, uploadId]); const [createSignedDocumentUrl] = useMutation<{ signAdminUploadUrl: string }>( SIGN_FILE_MUTATION, { onError: console.error, onCompleted: (urlData) => { const signedUrl = urlData.signAdminUploadUrl; window.open(signedUrl, '_blank', 'noreferrer'); }, }, ); return isNonEmptyString(fileUrl) ? ( <ExternalLink onClick={() => void createSignedDocumentUrl({ variables: { url: fileUrl } })} text={fileName ?? ''} /> ) : undefined; };
Chaque fois que je télécharge un fichier à l'aide de ce composant, j'obtiens une erreur de réaction渲染的钩子比上次渲染期间更多。
. React indique que l'ordre des hooks a changé comme suit
client.js:1 Warning: React has detected a change in the order of Hooks called by BusinessProcessDetails. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks Previous render Next render ------------------------------------------------------ 1. useContext useContext 2. useContext useContext 3. useContext useContext 4. useContext useContext 5. useRef useRef 6. undefined useState
En regardant mon code, je n'arrive pas à comprendre pourquoi cette erreur se produit. React dit que c'est la première ligne du composant qui appelle useState qui provoque l'erreur, mais cela n'a aucun sens pour moi. L'appel d'un hook réactif sans conditions provoque cela, et la première ligne du composant qui génère cette erreur ne correspond pas à l'ordre dans lequel le hook a changé.
J'utilise React 18.2.0, TypeScript 4.9.5
Il s'avère que le problème réside dans la façon dont le composant est appelé. Le rendu du composant parent
FileUploadLink
ressemble à ceciLe correctif consiste à envelopper le composant dans une balise, c'est-à-dire