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

【Bug Report】"Emoji" component is not working for Next.js #607

Closed
kazuki-komori opened this issue Jun 4, 2022 · 21 comments
Closed

【Bug Report】"Emoji" component is not working for Next.js #607

kazuki-komori opened this issue Jun 4, 2022 · 21 comments

Comments

@kazuki-komori
Copy link

kazuki-komori commented Jun 4, 2022

Problem

When "Emoji" Component use with Next.js (SSR), the Error has been occurred like below.

Unhandled Runtime Error TypeError: Class constructor $8b28a44b07620e42$export$2e2bcd8739ae039 cannot be invoked without ‘new’
const Emoji = dynamic<EmojiProps>(
  () => import("emoji-mart").then((m) => m.Emoji),
  {
    ssr: false,
  }
);

export const Foo = () => {
  return (
    <Emoji emoji={"thinking_face"} size={64} />
  );
};

Reference

However, "Picker" component is available for Next.js

const Picker = (props = {}) => {
  const ref = useRef()

  useEffect(() => {
    import('emoji-mart').then((EmojiMart) => {
      new EmojiMart.Picker({ ...props, data, ref })
    })
  }, [])

  return <div ref={ref}/>
}

Example code is here.
#575 (comment)

Environment

- next v12.1.6
- Node.js v14.19.0
- TypeScript v4.7.3
@austinbuckler
Copy link

see: #575 (comment)

@kazuki-komori
Copy link
Author

kazuki-komori commented Jun 6, 2022

@austinbuckler
Thank you for your reply !
I saw your comment, I understand "Picker" component is able to use dynamic import and ref callback function.

So.., I want to know, how to display "Emoji" component, by use of dynamic import and ref callback function.
Could you give me some example?

@marekves
Copy link

marekves commented Jun 7, 2022

@austinbuckler Thank you for your reply ! I saw your comment, I understand "Picker" component is able to use dynamic import and ref callback function.

So.., I want to know, how to display "Emoji" component, by use of dynamic import and ref callback function. Could you give me some example?

Any updates on this?

@austinbuckler
Copy link

@austinbuckler Thank you for your reply ! I saw your comment, I understand "Picker" component is able to use dynamic import and ref callback function.

So.., I want to know, how to display "Emoji" component, by use of dynamic import and ref callback function. Could you give me some example?

I can take a look sometime tonight/this week. I don't have a use-case for the Emoji component, I didn't know such a thing existed.

@saurabhmehta1601
Copy link

I am using Picker in Nextjs . This method works fine .

EmojiPicker.jsx

import React, { useEffect, useRef } from "react";
import data from "@emoji-mart/data";
import { Picker } from "emoji-mart";

const EmojiPicker = (props) => {
  const ref = useRef(null);

  useEffect(() => {
    new Picker({ ...props, data, ref });
  }, []);

  return <div ref={ref} />;
};

export default EmojiPicker;

The file where you want to use EmojiPicker component .

Page.jsx

import React from "react"
import dynamic from "next/dynamic"

const EmojiPicker = dynamic(() => import("./EmojiPicker"), {
  ssr: false,
});

const Page = () => {
  return <EmojiPicker />
}

export default Page

@kazuki-komori
Copy link
Author

@saurabhmehta1601
Thanx !
By the way, do you know how to use Emoji component ?

@saurabhmehta1601
Copy link

saurabhmehta1601 commented Jun 15, 2022

Yeah you can pass function onEMojiSelect inside Picker object which triggers whenever emoji is selected from the emoji picker . Here is how to do it :

EmojiPicker.jsx

const EmojiPicker = (props) => {
  const ref = useRef(null)

  useEffect(() => {
    new Picker({
      ...props,
      data,
      onEmojiSelect: (emoji) => {
      // You can grab selected emoji here and do what you want with it 
        console.log("selected emoji is " , emoji.native)
      },
    });
  }, []);

  return <div ref={ref} />;
};

export default EmojiPicker;

@kazuki-komori
Copy link
Author

@saurabhmehta1601
Thanks!
I could understand usecase !

@321ckatz123
Copy link

321ckatz123 commented Jun 21, 2022

Any update on using Emoji directly in React in next (FWIW, this is the same error without using Next.js. Just referencing the Emoji component in React throws the same error).

If we are no longer supposed to use it (looking at the examples, seems like it), can we get an example of the "correct" way to use Emoji inside React?

@EtienneLem
Copy link
Member

Have you tried using the custom HTML element <em-emoji>? You can see examples here https://github.com/missive/emoji-mart/blob/main/packages/emoji-mart-website/example-emoji-component.html

@321ckatz123
Copy link

321ckatz123 commented Jun 23, 2022

@EtienneLem so I tried that and it does work (I have an example below), but I think the main point we are calling out is that we can still access

import { Emoji } from 'emoji-mart'

and it returns a React component that just fundamentally doesn't work (and blows up with the error above). Picker has the same problem (though there is a React example for that already)

It seems as a whole like this library moved away from React components (which is your prerogative to do), it's just confusing that we can still access them, but they don't "work" and there's no way that we can find to make them work. If this library chooses to no longer support React, that's totally cool... just please remove the ability for us to import something that looks like it should work.

For those who run into this issue, I created a custom component that wraps the em-emoji component as called out by @EtienneLem.

Depending on your use case, it likely needs to be changed or improved on, and this is essentially a PoC, but as I just need to show the emoji, this worked good enough for me (NOTE: your mileage may vary as there are some interesting default styles being applied to the emoji itself that might cause issues).

import { init } from 'emoji-mart';
import data from '@emoji-mart/data/sets/14/apple.json';

init({ data });

function Emoji({ emoji, size = '24px' }) {
  return <em-emoji set="apple" id={emoji} size={size} />;
}

export default Emoji;

@EtienneLem
Copy link
Member

Right, ok. Again, all because of lack of documentation. Broken record here, but sorry for not having properly updated docs yet. Very soon, I promise.

A few things:

1. init

init() is indeed required in order for <em-emoji> to work. Initializing a picker first (once) would also work. That is because data needs to be provided for the emoji component to be usable.

2. import { Emoji } from 'emoji-mart'

This is not a React component. This is an HTMLElement and can therefore be used with React (and any other web framework).

Emoji is exported, but that’s questionable. Usage currently relies on <em-emoji> in your HTML (via React or anything else).

@321ckatz123
Copy link

@EtienneLem thanks for the update.

The confusing part for us was that

import { Emoji } from 'emoji-mart'

used to be a valid React component and is still exported (which I think you were alluding to, no longer needs to be the case).

Totally can appreciate that this is likely a lack of documentation that is causing confusion :).

A few questions for you

  1. Just to be clear, init only needs / should be run once for an application? If I have a SPA, I can call init once and then use the Picker and Emoji stuff (in whatever form) and everything should be happy?
  2. Is there an appetite to re-expose proper React components in this or another "official" library?

@EtienneLem
Copy link
Member

  1. Just to be clear, init only needs / should be run once for an application? If I have a SPA, I can call init once and then use the Picker and Emoji stuff (in whatever form) and everything should be happy?

Correct!

Even if you were to call it multiple times, it wouldn’t currently change anything. That’s an issue that is going to be addressed in #588.

  1. Is there an appetite to re-expose proper React components in this or another "official" library?

I wouldn’t necessarily mind exporting a EmojiPicker.jsx and, why not, any other framework wrappers if need be. But you would still need to import and provide the data, so at the end you would most likely still need a component on your end to wrap the wrapper.

@321ckatz123
Copy link

321ckatz123 commented Jun 23, 2022

@EtienneLem FWIW, for your answer to 2, you are describing a relatively common pattern in React that follows the Provider pattern using the internal context library.

To be honest, I kind of have to make it all work in React and your answer to 1 means that I can follow that pattern. Are you amenable to me creating a PR that creates the Provider, Picker, and Emoji React component within this repo?

Also, while I am not the OP, I think this issue can be closed. While yes, this does explode when trying to use it this way, this is a known and expected part of the v5 upgrade and we have answered how to solve it.

@EtienneLem
Copy link
Member

Are you amenable to me creating a PR that creates the Provider, Picker, and Emoji React component within this repo?

Sure thing! 🤗

@EtienneLem
Copy link
Member

React issues have been addressed in v5.2.0. You can use @emoji-mart/react now.

See https://github.com/missive/emoji-mart#-emoji-component for the <em-emoji> usage.

@s0-david
Copy link

s0-david commented Oct 5, 2022

It says "Property 'em-emoji' does not exist on type 'JSX.IntrinsicElements'" on next.js. How do I fix this warning?

@kuzzmi
Copy link

kuzzmi commented Nov 18, 2022

It says "Property 'em-emoji' does not exist on type 'JSX.IntrinsicElements'" on next.js. How do I fix this warning?

I added the following to .d.ts to work this around. Not sure whether that was a good idea to use web component in JSX:

import * as React from "react";

declare global {
  namespace JSX {
    interface IntrinsicElements {
      "em-emoji": React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement>,
        HTMLElement
      > & {
        id?: string;
        shortcodes?: string;
        native?: string;
        size?: string | number;
        fallback?: string;
        set?: "native" | "apple" | "facebook" | "google" | "twitter";
        skin?: string | number;
      };
    }
  }

@christopherarm
Copy link

It says "Property 'em-emoji' does not exist on type 'JSX.IntrinsicElements'" on next.js. How do I fix this warning?

I added the following to .d.ts to work this around. Not sure whether that was a good idea to use web component in JSX:

import * as React from "react";

declare global {
  namespace JSX {
    interface IntrinsicElements {
      "em-emoji": React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement>,
        HTMLElement
      > & {
        id?: string;
        shortcodes?: string;
        native?: string;
        size?: string | number;
        fallback?: string;
        set?: "native" | "apple" | "facebook" | "google" | "twitter";
        skin?: string | number;
      };
    }
  }

Can you integrate this into the package ? I have to paste it every time when I pull my repo

@neznayer
Copy link

neznayer commented Feb 24, 2023

It says "Property 'em-emoji' does not exist on type 'JSX.IntrinsicElements'" on next.js. How do I fix this warning?

I added the following to .d.ts to work this around. Not sure whether that was a good idea to use web component in JSX:

import * as React from "react";

declare global {
  namespace JSX {
    interface IntrinsicElements {
      "em-emoji": React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement>,
        HTMLElement
      > & {
        id?: string;
        shortcodes?: string;
        native?: string;
        size?: string | number;
        fallback?: string;
        set?: "native" | "apple" | "facebook" | "google" | "twitter";
        skin?: string | number;
      };
    }
  }

Could anyone tell me, where should I paste this? what folder and filename should it be? For now, I've tried src/em-emoji.d.ts but no effect... And should I then reference that path somewhere?

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

No branches or pull requests

10 participants