react-player icon indicating copy to clipboard operation
react-player copied to clipboard

Application Error with Remix v2?

Open genmon opened this issue 2 years ago • 7 comments
trafficstars

Current Behavior

Using ReactPlayer with Remix v2 out of the box triggers an Application Error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Expected Behavior

I would expect the player to appear, as it did in Remix v1.

Steps to Reproduce

I have a minimal repro here: remix-v2-reactplayer-minimal

This is the stock Remix v2 starter template

Other Information

I am not experienced with Remix v2 so it is possible I am missing something obvious. Would be grateful if anyone else could let me know whether I'm seeing an incompatibility, or if it's a setup problem.

genmon avatar Oct 12 '23 09:10 genmon

A colleague has provided me with a workaround:

// @ts-ignore bundling issue with react-player
const Player = ReactPlayer.default as typeof ReactPlayer;

A bundling problem, perhaps similar to #193 from 2017? I'll leave this issue open as it may connect to something else.

genmon avatar Oct 12 '23 10:10 genmon

I'm running into the same issue on Remix 2.1.0

tb-b avatar Oct 27 '23 13:10 tb-b

Same issue here, I'm working around it by using ReactPlayer.default, which makes typescript unhappy.

UncleGravity avatar Oct 31 '23 13:10 UncleGravity

This made it for me, also typescript it's happy about it:

import { useState } from 'react'

import ReactPlayer from 'react-player'
import Example_Video from '~/public/media/example-video.mov'

const Player = ReactPlayer.default

export function Video() {
  const [hasVideoLoaded, setHasIsVideoLoaded] = useState(false)

  return (
    <div className={`${hasVideoLoaded ? 'opacity-100' : 'opacity-0'} transition`}>
      <Player
        url={Example_Video}
        playing={true}
        muted={true}
        playsinline={true}
        onReady={() => setHasIsVideoLoaded(true)}
      />
    </div>
  )
}

Thanks to @genmon about the insights on it!

dev-xo avatar Nov 04 '23 23:11 dev-xo

Same issue here. I tried your fix @dev-xo but there is a type error on the line const Player = ReactPlayer.default (property does not exist).

import ReactPlayer from 'react-player/youtube' works perfectly. But it doesn't work for Vimeo, for instance.

Varkoff avatar Dec 04 '23 07:12 Varkoff

A colleague has provided me with a workaround:

// @ts-ignore bundling issue with react-player
const Player = ReactPlayer.default as typeof ReactPlayer;

A bundling problem, perhaps similar to #193 from 2017? I'll leave this issue open as it may connect to something else.

This issue is still present in Remix 2.4.1. We just switched to ESM module support and that switch demonstrated this issue. Using the above suggestion fixed our issue.

bartling-cce avatar Jan 07 '24 19:01 bartling-cce

You saved my day. I was looking for a solution for days!!!

EDIT: Well. The solution helped in the first place, but when I refresh the page I get a slightly different error.

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

SchattenGestalt avatar Jan 15 '24 02:01 SchattenGestalt

You can fix this with Client Only from remix-tools.

react-player.client.tsx:

import ReactPlayer from "react-player";
export default ReactPlayer;

video-player.tsx:

import { ClientOnly } from "~/components/client-only";
import ReactPlayer from "~/components/react-player.client";

export function VideoPlayer() {
  return (
      <ClientOnly fallback={<div>Video</div>}>
        {() => <ReactPlayer url={url} />}
      </ClientOnly>
  );
}

goldcaddy77 avatar Feb 25 '24 18:02 goldcaddy77

@goldcaddy77 Thx for your comment. That is, what I have finally done, but didn't mentioned it here.

SchattenGestalt avatar Feb 28 '24 09:02 SchattenGestalt