React表情搜索应用Props传递异常及渲染异常问题求助
Hey there! Let's break down what's causing those frustrating emoji display issues and fix them step by step.
Key Issues Causing the Problem
- Incorrect State Mutation: You're directly pushing to the
emojiIconsstate array withemojiIcons.push(...)— React state is immutable, so you can't modify it directly like this. You need to use the state setter function instead. - Missing useEffect Dependencies: Your
useEffecthas no dependency array, which means it runs every single render (including after state updates). This leads to unexpected behavior, especially on page refresh. - Broken Emoji Filtering Logic: The way you're calculating
emotionsand mapping toemojiIconsisn't tied to the searchcontentstate. Right now, it only runs once (or infinitely without dependencies) instead of updating when the user types. - Duplicate Emoji Key: You have two entries for
😇inemojiDescriptions— the second one overwrites the first, so that emoji will have incorrect search terms. - Minor Typo: "shoked" in the
😱entry should be "shocked" to ensure search works properly for that emoji.
Fixed SearchBar Component
import React, { useEffect, useState} from 'react'; import EmojiContainer from '../emoji-container/emojiContainer'; import { BeakerIcon } from '@heroicons/react/solid'; import './searchBar.scss' export default function SearchBar() { const [content, setContent] = useState(''); const [emojiIcons, setEmojiIcons] = useState([]); // Cleaned up emoji descriptions (removed duplicate 😇 entry, fixed typo) const emojiDescriptions = { '😀': ['happy', 'positive emotion', 'smile', 'smiling', 'every emoji', '0'], '😁': ['happy', 'smiley', 'smiling', 'positive emotion', 'every emoji', '1'], '😂': ['happy', 'smiley', 'smiling', 'smile', 'laugh', 'laughing', 'positive emotion', 'every emoji', '2'], '😆': ['happy', 'smiley', 'smiling', 'smile', 'laugh', 'laughing', 'positive emotion', 'every emoji', '3'], '😊': ['happy', 'smiley', 'positive emotion', 'smile', 'every emoji', '4'], '🙂': ['smile', 'smiling', 'every emoji', '5'], '🙃': ['smile', 'smiling', 'upside down face', 'every emoji', '6'], '😜': ['wink', 'winky face', 'every emoji', '7'], '😝': ['naughty face', 'laugh', 'laughing', 'every emoji', '8'], '😺': ['happy', 'positive emotion', 'smile', 'smiling', 'every emoji', '9'], '😸': ['happy', 'smiley', 'smiling', 'positive emotion', 'every emoji', '10'], '😹': ['happy', 'smiley', 'smiling', 'smile', 'laugh', 'laughing', 'positive emotion', 'every emoji', '11'], '😇': ['happy', 'smiley', 'smiling', 'smile', 'humble', 'innocent', 'innocense', 'every emoji', '12'], '😗': ['kiss', 'affection', 'every emoji', '13'], '😙': ['kiss', 'affection', 'every emoji', '14'], '😻': ['heart eyes', 'love', 'affection', 'cat', 'every emoji', '16'], '😍': ['heart eyes', 'love', 'affection', 'every emoji', '17'], '😡': ['angry', 'angry face', 'every emoji', '18'], '😈': ['angry', 'angry face', 'devil', 'devil face', 'every emoji', '19'], '👹': ['monster', 'angry monster', 'angry', 'every emoji', '20'], '👺': ['monster', 'every emoji', '21'], '💀': ['skull', 'every emoji', '22'], '👽': ['alien', 'every emoji', '23'], '👻': ['ghost', 'every emoji', '24'], '🤖': ['robot', 'every emoji', '25'], '💩': ['poop', 'eww', 'gross', 'every emoji', '26'], '😴': ['sleep', 'sleepy', 'sleepy face', 'every emoji', '27'], '💤': ['sleep', 'sleepy', 'every emoji', '28'], '🚚': ['truck', 'every emoji', '29'], '🤑': ['money', 'money eyes', 'every emoji', '30'], '😱': ['shocked', 'every emoji', '31'] }; useEffect(() => { // Filter emojis based on search content (case-insensitive for better UX) const filteredEmojis = Object.entries(emojiDescriptions) .filter(([_, descriptions]) => descriptions.some(word => word.toLowerCase().includes(content.toLowerCase())) ) .map(([emoji]) => emoji); // Update state correctly with React's setter function setEmojiIcons(filteredEmojis); }, [content]); // Only run when search content changes return ( <div className='search-bar-container'> <div className="title"> <BeakerIcon /> Emoji Search </div> <input type="text" className="search-bar" placeholder='Search for an emoji!' onChange={(e) => setContent(e.target.value)} value={content} /> <EmojiContainer emojis={emojiIcons} /> </div> ) }
Optimized EmojiContainer Component
We'll use the emoji itself as the key (instead of index) for more stable React rendering:
import React from 'react' import './emojiContainer.scss'; export default function EmojiContainer({ emojis }) { return ( <ul className='emoji-container'> {emojis.map((emoji) => ( <li className='emoji' key={emoji}>{emoji}</li> ))} </ul> ) }
What Changed & Why?
- Immutable State Updates: Instead of mutating the
emojiIconsarray directly, we usesetEmojiIconsto replace it with filtered results — this follows React's state rules and prevents unexpected re-renders. - Targeted useEffect: The effect now only runs when the search
contentchanges, keeping the emoji list in perfect sync with user input. - Simplified Filtering: We use
Object.entriesto work with both emoji keys and their descriptions, making the logic more readable and avoiding the confusing slice/parseInt step you had before. - Case-Insensitive Search: Users can type "Happy" or "happy" and get the same results, which is more intuitive.
- Stable Keys: Using the emoji as the key ensures React doesn't re-render emoji items unnecessarily when the list filters.
内容的提问来源于stack exchange,提问作者Marwane Elalama
相关产品推荐
相关产品推荐

