You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何避免匿名函数?含React.memo子组件传参场景

Fixing Unnecessary Re-renders with React.memo When Passing Parameterized Callbacks

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:

  • handleClick has a stable reference thanks to useCallback and an empty dependency array.
  • userId is a primitive value (string/number), so React.memo can 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 userId or handleClick actually 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 handleClick function has a stable reference (thanks to useCallback).
  • When we call handleClick(user.id), it returns a function that's pre-bound to that specific ID. Since user.id is stable for each user, this returned function will only change if user.id changes—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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:37:54