搜索

首页  >  问答  >  正文

在没有使用条件钩子的情况下,在组件上呈现比之前渲染错误更多的钩子

我有以下组件,可以呈现文件上传的可点击链接

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

每次我使用此组件上传文件时,都会收到反应错误渲染的钩子比上次渲染期间更多。。 React 表示 hooks 的顺序发生了以下变化

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

查看我的代码,我无法理解为什么会发生此错误。 React 说是调用 useState 的组件的第一行导致了错误,但这对我来说毫无意义。没有条件调用反应钩子会导致这种情况,并且抛出此错误的组件的第一行与钩子更改的顺序不相符。

我正在使用react 18.2.0,typescript 4.9.5

P粉331849987P粉331849987447 天前599

全部回复(1)我来回复

  • P粉148434742

    P粉1484347422023-09-10 20:47:31

    事实证明问题出在组件的调用方式上。呈现 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,
        },
      ];

    回复
    0
  • 取消回复