Struggling to package React components inside a plugin

default discord avatar
noheadphones
7 months ago
29

I've been working on

https://github.com/NouanceLabs/payload-dashboard-analytics

and trying to build out the logic for fetching analytics data via an API and then exposing it in the Payload admin panel via custom components. However I simply can't seem to be able to use any React hooks inside my custom components as I get a React error about invalid hook use. The component is here

https://github.com/NouanceLabs/payload-dashboard-analytics/blob/main/src/components/Charts/ViewsChart.tsx

I cross referenced my implementation with the SEO plugin

https://github.com/payloadcms/plugin-seo

and the lexical plugin and for the life of me I can't seem to figure out where I'm going wrong.



I've attached a video showing how just one hook breaks the admin panel entirely.



@Alessio 🍣 @jmikrut any ideas?



I checked for duplicate or incorrect react versions, didn't find anything 😟



Edit: this similar error happens if I try to bundle a component in the

admin

panel directly like in

beforeDashboard

, didn't see any example of a plugin specifically dealing with that

  • discord user avatar
    jmikrut
    Payload Team
    7 months ago

    well



    from your vid i see this as strange:





    this might be something to do with that ViewsChart component itself specifically



    does the error go away if you completely remove the ViewsChart, even in the below function?



    the first error, i have never seen before. But the second errors about invalid hooks, I see all the time. What is inside the

    ViewsChart

    component? Is it a library? Does it come with its own React version? If you type

    yarn why react

    do you have more than one copy installed?



    generally i'd want to get to the bottom of why there are more than one react copies installed (which i am 99% confident is the problem here)



    but another way you can fix this is if you just simply alias react and react-dom to ONE copy of react



    example:



    webpack: config => {
      const newConfig = {
        ...config,
        resolve: {
          ...(config.resolve || {}),
          alias: {
            ...(config.resolve.alias || {}),
            react: path.resolve(__dirname, '../node_modules/react'),
          },
        },
      }
      return newConfig
    },
    image.png
  • default discord avatar
    Alessio 🍣
    7 months ago

    does anything speak against making that the standard for every single project?

  • discord user avatar
    jmikrut
    Payload Team
    7 months ago

    kinda, because it can "obscure" issues that should otherwise be solved



    but i'm not opposed to it



    really you should not have to install multiple copies / different versions of react

  • default discord avatar
    noheadphones
    7 months ago

    I haven't been able to reproduce this first error actually...so I commented out all hooks within the component, and it renders fine with no react warnings or errors...that one might've been just during that compilation



    The output of why react is


    [1/4] Why do we have the module "react"...?
    [2/4] Initialising dependency graph...
    [3/4] Finding dependency...
    [4/4] Calculating file sizes...
    => Found "react@18.2.0"
    info Has been hoisted to "react"
    info Reasons this module exists
       - Specified in "devDependencies"
       - Hoisted from "payload#react"
    info Disk size without dependencies: "388KB"
    info Disk size with unique dependencies: "420KB"
    info Disk size with transitive dependencies: "448KB"
    info Number of shared dependencies: 2
  • discord user avatar
    jmikrut
    Payload Team
    7 months ago

    it's in your

    devDependencies

    ?



    you could probably remove it from there



    that might be the cause

  • default discord avatar
    noheadphones
    7 months ago

    Removed it and still getting errors with the hooks



    I find it odd because the seo plugin has


    "peerDependencies": {
        "payload": "^0.18.5 || ^1.0.0",
        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
      },
      "devDependencies": {
        "payload": "^1.0.9",
        "react": "^18.0.0",
        "typescript": "^4.5.5"
      },
  • discord user avatar
    jmikrut
    Payload Team
    7 months ago

    that's a good question



    i would guess that in dev mode, that plugin does alias react



    like, for local dev of the plugin itself

  • default discord avatar
    noheadphones
    7 months ago

    Omg yes



    webpack: (config) => {
          const newConfig = {
            ...config,
            resolve: {
              ...config.resolve,
              alias: {
                ...config.resolve.alias,
                react: path.join(__dirname, "../node_modules/react"),
                "react-dom": path.join(__dirname, "../node_modules/react-dom"),
                payload: path.join(__dirname, "../node_modules/payload"),
              },
            },
          };
    
          return newConfig;
        },


    Except it aliases everything, this seems to fix it!



    Thanks a lot!

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.