Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic React Dashboard blank (opacity: 0) on version upgrade with Next.js #4209

Closed
2 tasks done
jeremyis opened this issue Nov 10, 2022 · 4 comments · Fixed by #4223
Closed
2 tasks done

Basic React Dashboard blank (opacity: 0) on version upgrade with Next.js #4209

jeremyis opened this issue Nov 10, 2022 · 4 comments · Fixed by #4223
Labels

Comments

@jeremyis
Copy link

jeremyis commented Nov 10, 2022

Initial checklist

  • I understand this is a bug report and questions should be posted in the Community Forum
  • I searched issues and couldn’t find anything (or linked relevant results below)

Link to runnable example

Steps to reproduce

I had actually upgraded from @uppy/core 2.3.0 -> 3.0.4 so perhaps something in my upgrade has gone wrong. I tried reinstalling fresh and going through the docs and multiple variations thereof. No success.

I had also recently upgraded from React 17 to 18 and Next.js from 12.1 -> 12.3. I am not usre if this had any impact.
I have been using react bootstrap (don't ask).

npm diff:
image

Code:

import AwsS3Multipart from "@uppy/aws-s3-multipart";
import React, { useId } from "react";
import Uppy from "@uppy/core";
import { useUppy, Dashboard } from "@uppy/react";
import "@uppy/core/dist/style.css";
import "@uppy/dashboard/dist/style.css";
import FileInput from "@uppy/file-input";

interface Props {
  onUploadSuccess: (localFilePath: string, url: string) => void;
  serverBaseUrls: ServerBaseUrls;
  allowedFileTypes?: MimeType[];
}
const companionUrl= ""; // Is set in actual code.
export function FileUploadComponent(props: Props) {
  const uppyId = useId();
  const uppy = useUppy(() => {
    let restrictions = {
      maxFileSize: 300 * 1024 * 1024,
      ...(props.allowedFileTypes ? { allowedFileTypes: props.allowedFileTypes } : {}),
    };
    return new Uppy({
      id: `uppy-${uppyId}`,
      debug: true,
      autoProceed: false,
      allowMultipleUploadBatches: true,
      restrictions,
    })
      .use(FileInput)
      .use(AwsS3Multipart, {
        limit: 4,
        retryDelays: [0, 1000, 3000, 5000, 10000],
        companionUrl,
      })
      .on("upload-success", (uppyFile, response) => {
        if (!response.uploadURL) {
          throw new Error(
            `No upload URL for file upload. Response: ${JSON.stringify(response)}`
          );
        }
        //console.log(["uppy-upload-success", uppyFile, uppyFile?.meta?.name, response.uploadURL]);
        const localFilePath = (uppyFile?.meta?.relativePath as string) || uppyFile?.meta?.name;
        if (!localFilePath) {
          throw new Error("No localFilePath found on Uppy upload");
        }
        props.onUploadSuccess(localFilePath, response.uploadURL);
      });
  });

  return (
    <Dashboard
      uppy={uppy}
      disabled={false}
      plugins={["DragDrop", "FileInput"]}
      fileManagerSelectionType={"both"}
      showProgressDetails={true}
    />
  );
}

note: I get the same behavior with / without the .use(FileInput)

Expected behavior

note: .uppy-Dashboard-innerWrap has opacity: 0. When I manually override that, I get:
image

I found a somewhat related issue: #1571

Actual behavior

<Dashboard> renders as:
image

Basic React Dashboard rendering Blank window. When I override the CSS, file upload no-ops. I'll get a "file selector" but selecting files doesn't update the UI. (my suspicion is startListeningToResize (and likely its parents) is never
called. See: #1383

@jeremyis
Copy link
Author

jeremyis commented Nov 11, 2022

I think this workaround works but is very hacky.

Same code as above ,except the return statement is substittued for this code block

  // HACK to prevent
    useEffect(() => {
      const hasDashboardPlugin = uppy.getState().plugins?.["react:Dashboard"];
      const dashboardIsHidden = uppy.getState().plugins?.["react:Dashboard"]?.isHidden;
      if (hasDashboardPlugin && dashboardIsHidden) {
        const newState = {
          ...uppy.getState(),
          plugins: {
            ...(uppy.getState().plugins ?? {}),
            "react:Dashboard": {
              ...(uppy.getState().plugins?.["react:Dashboard"] ?? {}),
              isHidden: false,
            },
          },
        };
        uppy.setState(newState);
        setShowDashboard(true); // To trigger a re-render; only  uppy.setState(newState); doesn't seem to trigger a re-render
      }
    }, [uppy.getState()]);

    return (
      <div>
        <Dashboard
          uppy={uppy}
          disabled={!showDashboard}
          fileManagerSelectionType={"both"}
          showProgressDetails={true}
          proudlyDisplayPoweredByUppy={false}
        />
      </div>
    );

@jeremyisatrecharm
Copy link

jeremyisatrecharm commented Nov 13, 2022

So it looks like the issue only happens locally with Next (I am running vercel dev). I think prod worked just fine (actually with the disabled prop set to true, I was getting a grayed-out UI that still functioned).

This is very hacky but I just did this and it works both locally and in prod:

    useEffect(() => {
      setTimeout(() => {
        setShowDashboard(true);
      }, 500);
    }, []);

    return (
      <div>
        {showDashboard ? (
          <Dashboard
            uppy={uppy}
            fileManagerSelectionType={"both"}
            showProgressDetails={true}
            height={300}
            width={400}
            proudlyDisplayPoweredByUppy={false}
          />
        ) : (
          <Spinner variant="secondary" animation="border" />
        )}
      </div>
    );```

@Murderlon
Copy link
Member

Murderlon commented Nov 14, 2022

Interesting, as of React 18, I think the development renders twice to catch inconsistencies. So this might be related to #3935

@aspian-io
Copy link

aspian-io commented Nov 16, 2022

Some other packages like react-player not working as expected with reactStrictMode: true in NextJS 13.0.2 and React 18.2.0 development envioronment. So, I changed reactStrictMode value to false in next.config.js and after that, uppy/react 3.0.2 and other incompatible packages work fine.

I just wanted to mention that when you're using uppy-react like this, there are some other issues like upload-success event being called multiple times after uploading recorded audio from uppy audio component usually after recording and uploading for the second time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants