Comments (8)
Thank you for your comprehensive explanation. I appreciate the suggested strategies on how to handle the issue.
I believe the most consistent approach would be to make the user responsible for handling re-renders. In other words, you should shift towards utilizing the standard export default React.memo(EmojiPicker)
strategy instead of the current memoization logic (where you ignore non-primitive prop changes). This means that EmojiPicker would re-render whenever the parent renders due to non-primitive prop changes.
However, this is precisely why we should use React.useCallback
, a standard that gracefully passes the responsibility of limiting unnecessary re-renders to the user. Here's what I mean:
// ...
const onEmojiClick = React.useCallback((emoji: EmojiClickData) => {
alert(`Current state: ${myState}`);
}, [myState]);
// ...
<EmojiPicker onEmojiClick={onEmojiClick} />
Notably, this triggers the picker to only re-render when the state value changes, and not every time the parent does. But if users would still like to limit re-renders of the picker even further, they are welcome to use refs instead by having an empty dependency array in the useCallback
declaration, with myState
as a ref.
This approach maintains what I believe most users anticipate when interacting with external libraries. While it's true that it may not be suitable for every scenario, it has the advantage of aligning with widespread, standardized practices.
Nevertheless, if I were to choose between one of the proposed strategies, I'd go for the first one - a mem-key prop that would allow us to manually trigger re-renders of the EmojiPicker component.
Let me know if you have any comments or need further clarification on the proposed approach.
from emoji-picker-react.
Sorry for not responding earlier. @TKasperczyk, It's been quite difficult to concentrate on OSS work during the current war situation.
@cr0ybot, as a workaround until I introduce one of these options that I described above (or go with @TKasperczyk's suggestion), one of these could work:
- use refs
- do not reference the state in your onEmojiClick function, but rather only set the next state using a callback function
- add a
key
property to the picker. Its value should be your current emoji state.
from emoji-picker-react.
@cr0ybot try 4.5.3. I just releaesd it a few minutes ago. It is possible that it will solve it for you, if not, can you share with me a repro sandbox? I will try to get this fixed.
from emoji-picker-react.
Hey @TKasperczyk, as you noted correctly, the most straightforward workaround is to use refs. But, as you also mentioned, it is cumbersome and counter intuitive.
I'll shed some light on what's going on, and let's try to find together a solution for it that would be viable for you.
The reason onEmojiClick gets an outdated state reference is the internal memoization of the picker. The picker uses memeoizeation because otherwise, each state update outside of the picker would trigger full rerender of all emojis (1000s of elements), which would cause significant lag. Instead, I memoize by all primitive props. The others are not factored in (cannot compare a function, for example), so state update outside of the picker do not change the onEmojiClick reference.
There are two ways to handle it, as I see it:
-
Simple, requires additional prop:
Add another prop that serves as your external mem-key, it will trigger an update each time it changes.
It is the simples to add on my end, but would be harder to discover, and require yet another step on your end. -
More complex, without API changes
Store all non-primitives in an internal ref, and pass them down regardless of memoization stage. This is slightly more complex on the internal picker implementation, and the main drawback is that it might miss some cases (as you experience now).
How would you, as a consumer, want to use it?
from emoji-picker-react.
I was pulling my hair out trying to figure out why I couldn't build an additive string of emojis with onEmojiClick
, even using useCallback
.
Is there really no way to update the internal ref of onEmojiClick
while also not rerendering the entire component? Or is it just that you want a holistic solution for all props instead of only onEmojiClick
?
from emoji-picker-react.
@TKasperczyk
I agree that this would give more granular control to the consumer side, and this is also something that's quite standard, but I am looking at it slightly differently.
Essentially, what you're describing is a prerequisite to using the picker, meaning, everyone who wants to use the picker will have to do this. 100% boilerplate code that all consumers need to add. In that case, I want to reduce that and have it a part of the picker.
As you noted, adding the ref on your end solves it, but it is icky, because it requires working around the component. I imagine having everyone use useCallback as a similar thing.
I think that regardless of what I pick as an api change I will make that internal ref thing that I mentioned to unbreak most existing use-cases, and this will give us some time to discuss a longer-term solution.
from emoji-picker-react.
@ealush Thanks for you work on this, it works now with useCallback
!
from emoji-picker-react.
Closing, since this is no longer an issue
from emoji-picker-react.
Related Issues (20)
- Custom emojis HOT 2
- Size of the library + SSR HOT 2
- Question: How to put apple smile in my input? (React)
- Enable/disable images as source for emojis HOT 2
- i wish there will be `how to run` section at readme file HOT 2
- Missing & double emojis on Windows 11 HOT 3
- can't select "hand with fingers splayed" emoji in any skin colour other than Neutral HOT 5
- Can't load custom emojis from an API call. HOT 7
- 无法只需要部分表情 HOT 2
- how about upgrade project to use current node version? HOT 2
- `npm install` & `npm run storybook` instructions at contributing.md. should it be `yarn` & `yarn storybook`?
- Emojis aren't appearing on macOS Sonoma Chrome until hovering over them HOT 2
- emoji.length is 5 for some emojies and 2 for some HOT 1
- not working in electron windows. HOT 9
- Can I choose several emojis to form a group? And configure its navigation and header? HOT 5
- aria-label and title in Clear button HOT 1
- Accessible names of icons HOT 3
- Emoji Picker is downloading a ton of png emojis every render HOT 1
- emoji image loading failed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from emoji-picker-react.