首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React Hooks: memoize click handlers for list?

React Hooks: memoize click handlers for list?
EN

Stack Overflow用户
提问于 2019-06-27 07:10:48
回答 1查看 527关注 0票数 3

我正在尝试呈现一个项目列表,每个项目都有一个按钮,当按下该按钮时,将切换下拉菜单。

我的代码看起来像这样:

代码语言:javascript
复制
function ItemList({items}) {
  const [isDropdownExpanded, setIsDropdownExpanded] = useState(null);
  const itemClickHandlers = useMemo(() => {
    const handlers = {}
    items.forEach(item => {
      handlers[item.id] = value => setIsDropdownExpanded(value ? item.id : null);
    });
    return handlers;
  }, [items.map(item => item.id).join(',')]);
}
return (
  <ul>
  {items.map(item =>
    <li onClick={itemClickHandlers[item.id]}>
      <Item name={item.name} isDropdownExpanded={isDropdownExpanded === item.id}/>
    </li>
  )}
  </ul>
);

上面的代码可以工作,但在用户添加或删除列表中的项目时会浪费呈现时间。(itemClickHandlers生成一个包含所有新处理程序的新对象,即使只应创建或删除一个处理程序,因此列表中的每一项都会重新呈现,因为通过引用相等,isDropdownExpanded将不相等。)

最好只使用功能React组件,当项目列表发生变化时,如何以最少的重新呈现来呈现这样的项目列表?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-27 13:04:38

您不需要为数组中的每一项都使用处理程序。您只需要有一个处理程序来传递id,如果将id添加到li元素上,则可以从event获得该id

代码语言:javascript
复制
function ItemList({items}) {
  const [isDropdownExpanded, setIsDropdownExpanded] = useState(null);
  const itemClickHandlers = useCallback((e) => {
      const id = e.currentTarget.id;
      setIsDropdownExpanded(prev => (prev != id ? id: null));
  }, [])

    return (
      <ul>
      {items.map(item =>
        <li key={item.id} id={item.id} onClick={itemClickHandler}>
          <Item name={item.name} isDropdownExpanded={isDropdownExpanded === item.id}/>
        </li>
      )}
      </ul>
    );
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56782006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档