Beim Rendern von Komponenten treten mehr als bei früheren Renderfehlern auf, ohne dass bedingte Hooks verwendet werden
P粉331849987
P粉331849987 2023-09-09 22:36:14
0
1
595

Ich habe die folgende Komponente, die einen anklickbaren Link zum Hochladen von Dateien rendert

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;
};

Jedes Mal, wenn ich mit dieser Komponente eine Datei hochlade, erhalte ich einen Reaktionsfehler渲染的钩子比上次渲染期间更多。. React zeigt an, dass sich die Reihenfolge der Hooks wie folgt geändert hat

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

Wenn ich mir meinen Code ansehe, kann ich nicht verstehen, warum dieser Fehler auftritt. React sagt, dass es die erste Zeile der Komponente ist, die useState aufruft, die den Fehler verursacht, aber das ergibt für mich keinen Sinn. Dies wird durch den Aufruf eines reaktiven Hooks ohne Bedingung verursacht, und die erste Zeile der Komponente, die diesen Fehler auslöst, stimmt nicht mit der Reihenfolge überein, in der sich der Hook ändert.

Ich verwende React 18.2.0, Typescript 4.9.5

P粉331849987
P粉331849987

Antworte allen(1)
P粉148434742

事实证明问题出在组件的调用方式上。呈现 FileUploadLink 的父组件看起来像这样

export const MyComponent = ({ fileUpload }: MyProps) => {
  const values = [
    {
      label: 'MyLabel',
      value: fileUpload ? FileUploadLink({ uploadId: fileUpload }) : undefined,
    },
  ];

  return (
    <>
      {values.map((l, v) => {
        <div>{l}</div>;
        {
          v;
        }
      })}
    </>
  );
};

修复方法是将组件包装在标签中,即

const values = [
    {
      label: 'MyLabel',
      value: fileUpload ? <FileUploadLink uploadId={fileUpload} /> : undefined,
    },
  ];
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage