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

emoji-mart rendering duplicate emoji pickers #617

Closed
klukreativ opened this issue Jun 10, 2022 · 5 comments
Closed

emoji-mart rendering duplicate emoji pickers #617

klukreativ opened this issue Jun 10, 2022 · 5 comments

Comments

@klukreativ
Copy link

klukreativ commented Jun 10, 2022

have recently started using this package. Followed instructions but whenever I call on emoji-mart it displays two emoji-pickers instead of one.

import React, { useEffect, useRef } from 'react'
import { render } from 'react-dom'

import data from '@emoji-mart/data'
import { Picker } from 'emoji-mart'

export default function Test() {
    function EmojiPicker(props) {
        const ref = useRef()
      
        useEffect(() => {
          new Picker({ ...props, data, ref })
        }, [])
      
        return <div ref={ref} />
      }

    return(
        <EmojiPicker onEmojiSelect={console.log} />
    )
}

Screenshot 2022-06-10 003412

@vadholovin
Copy link

The bug occurs in React Strict mode.

@johan-smits
Copy link

Is there a workaround available for now?

@bitofbreeze
Copy link

bitofbreeze commented Jun 17, 2022

Refs keep their value in the mount-unmount-mount pattern in React 18 strict mode so you can do

const executedRef = useRef(false);
useEffect(() => {
  if (executedRef.current) return;
  new Picker({});
  executedRef.current = true;
}, []);

@manhkien198
Copy link

Is there a workaround available for now?

@MathiasGilson
Copy link

I've fixed it like that

export default ({ onSelect, parentId, darkMode, ...props }) => {
    const ref: any = useRef()

    useEffect(() => {
        if (ref.current) ref.current.innerHTML = "" // clean current emoji picker

        new Picker({
            data: async () => {
                const response = await fetch("https://cdn.jsdelivr.net/npm/@emoji-mart/data")
                return response.json()
            },
            ref,
            onEmojiSelect: onSelect,
            searchPosition: "top",
            previewPosition: "none",
            navPosition: "top",
            autoFocus: true,
            theme: darkMode ? "dark" : "light",
            title: "",
            emoji: "",
            maxFrequentRows: 0,
            sheetSize: 32,
            perLine: 10,
            color: "#4285f4",
            ...props
        })
    }, [parentId]) // update only when parentId changes

    const renderEmojiPickerLoader = () => (
        <EmojiPickerLoader>
            <Skeleton.Button active={true} block={true} />
        </EmojiPickerLoader>
    )

    return (
        <Suspense fallback={renderEmojiPickerLoader()}>
            <div className={props.darkMode ? "dark" : ""} ref={ref} />
        </Suspense>
    )
}

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

6 participants