React中data.map is not a function报错求助:角色死亡信息渲染问题
data.map is not a function When Rendering Tibia Character Deaths Let's break down why you're hitting that map error and fix it step by step—plus we'll handle the "no deaths" case to prevent crashes too.
1. The Root Cause: Incorrect State Updates
Your main issue is how you're setting the playerDeath state. Right now you're using spread syntax to unpack the deaths array directly into setPlayerDeath, which turns your array state into individual values (not an array anymore). When you try to call map on a non-array, you get that error.
Same problem with currentPlayer: you initialized it as an array, but data.characters.data is a single character object—not an array. That'll cause errors when you try to access currentPlayer.name later.
2. Fixing the State Handling in useEffect
Update your useEffect to properly set the state with the full arrays/objects:
useEffect(() => { // Only fetch if query isn't empty to avoid unnecessary calls if (!query) return; fetch(BASE_URL) .then(res => res.json()) .then(data => { // currentPlayer is a single object, not an array setCurrentPlayer(data.characters.data); // Set playerDeath to the deaths array (or empty array if it doesn't exist) setPlayerDeath(data.characters.deaths || []); }) .catch(err => console.error("Error fetching data:", err)); // Add error handling! }, [query])
Key Changes:
- Removed the incorrect spread syntax for
setCurrentPlayerandsetPlayerDeath - Added
|| []todata.characters.deathsto ensureplayerDeathis always an array (even if the character has no deaths) - Added a check to skip fetch when
queryis empty - Added error handling to catch API issues
3. Fix Initial State Values
Update your state initializers to match the data types you're expecting:
const [currentPlayer, setCurrentPlayer] = useState({}); // Empty object, not array const [playerDeath, setPlayerDeath] = useState([]); // This part was correct, but we're now ensuring it stays an array
4. Safely Render the Character Data
Since currentPlayer starts as an empty object, you should add checks to avoid rendering until the data is loaded. You can either add a guard clause in the App component:
{Object.keys(currentPlayer).length > 0 && ( <SearchCharacter currentPlayer={currentPlayer} /> )}
Or update the SearchCharacter component to handle empty state directly:
const SearchCharacter = ({ currentPlayer }) => { if (!currentPlayer.name) return <p>Loading character data...</p>; return ( <div> <p>Player Name :{currentPlayer.name}</p> <p>Player Level :{currentPlayer.level}</p> <p>Player Vocation :{currentPlayer.vocation}</p> </div> ) }
5. Fix the Death Component Mapping
Your current map is trying to access death.death.reason—but looking at the Tibia API structure, each item in the deaths array is already the death object. Simplify the map and add a fallback for no deaths:
{playerDeath.length === 0 ? ( <p>This character has no recorded deaths.</p> ) : ( playerDeath.map((death, index) => ( <Death key={index} // Or use death.timestamp if available, index is a safe fallback reason={death.reason} level={death.level} /> )) )}
Note on Keys:
Using death.reason as a key might cause issues if the character died from the same reason multiple times. If the API returns a unique timestamp or id for each death, use that instead. Index is a reliable fallback if no unique identifier exists.
Final Check
With these changes, your app will:
- Never throw
map is not a functionbecauseplayerDeathis always an array - Handle characters with no deaths gracefully
- Avoid errors when accessing character data before it's loaded
- Catch and log any API fetch errors
内容的提问来源于stack exchange,提问作者NewbieAeg

