React中如何避免匿名函数?含React.memo子组件传参场景
Got it, let's tackle this issue head-on! The core problem here is that your anonymous onClick prop creates a brand new function reference every time the parent component re-renders. Since React.memo does a shallow comparison of props, it sees this new function as a change and re-renders the child—even when nothing else has changed.
Here are two clean, reliable ways to fix this while still passing the user.id parameter:
1. Pass the ID as a Separate Prop and Handle the Click in the Child
This is the most straightforward approach. We'll keep the click handler stable with useCallback, pass the user.id as a separate primitive prop, and let the child trigger the handler with the ID when clicked.
Parent Component:
import React, { useCallback } from 'react'; const Parent = () => { // useCallback keeps this function reference stable across re-renders const handleClick = useCallback((id) => { console.log(id); }, []); // Empty dependency array means this only creates once return ( <div> {users.map((user) => ( <Child key={user.id} {/* Always use a unique, stable key instead of index! */} userId={user.id} onClick={handleClick} /> ))} </div> ); }
Child Component:
import React from 'react'; const Child = React.memo(({ userId, onClick }) => { return ( <button onClick={() => onClick(userId)}> {/* Your child component content here */} </button> ); });
Why this works:
handleClickhas a stable reference thanks touseCallbackand an empty dependency array.userIdis a primitive value (string/number), soReact.memocan easily compare it to the previous prop.- The anonymous function inside the child is created only when the child re-renders, which now only happens if
userIdorhandleClickactually changes.
2. Use a Curried Handler with useCallback
If you prefer to keep the click logic closer to the parent, you can create a curried function with useCallback that returns the click handler pre-bound to the user ID.
Parent Component:
import React, { useCallback } from 'react'; const Parent = () => { // Curried function: returns a handler bound to the passed ID const handleClick = useCallback((id) => () => { console.log(id); }, []); return ( <div> {users.map((user) => ( <Child key={user.id} onClick={handleClick(user.id)} /> ))} </div> ); }
Child Component:
import React from 'react'; const Child = React.memo(({ onClick }) => { return ( <button onClick={onClick}> {/* Your child component content here */} </button> ); });
Why this works:
- The outer
handleClickfunction has a stable reference (thanks touseCallback). - When we call
handleClick(user.id), it returns a function that's pre-bound to that specific ID. Sinceuser.idis stable for each user, this returned function will only change ifuser.idchanges—not on every parent re-render.
Quick Note on Keys
I also swapped out index for user.id as the component key. Using indexes as keys can cause unexpected behavior in lists (like incorrect state retention) when items are added/removed. Always use a unique, stable identifier for each list item when possible!
内容的提问来源于stack exchange,提问作者Ahmed Waqas

