reactjs - react Hook : memoize click handlers for list?

标签 reactjs react-hooks

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

我的代码看起来像这样:

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 组件,当项目列表发生变化时,如何以最少的重新渲染来呈现这样的项目列表?

最佳答案

您不需要为数组中的每个项目处理程序。您所需要的只是拥有一个处理程序,您可以将 id 传递给该处理程序,如果您在 li 元素上添加 id

,则可以从事件中获取该 id
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>
    );
}

关于reactjs - react Hook : memoize click handlers for list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56782006/

相关文章:

javascript - useState 与异步函数返回 Promise {<pending>}

reactjs - react native : setState not updating immediately when logging in console

android - 为 iOS 和 Android 构建具有原生性能的混合 React 应用程序

javascript - 如何解决这个错误 "Uncaught TypeError: inputArgs[0].match is not a function"

javascript - 当主体函数进行条件检查时,useEffect 钩子(Hook)应该返回什么?

react-native - 使用一个对象跟踪 UI 元素状态,但一旦离开屏幕并返回,状态不会保留

reactjs - 如何将 useState 状态值传递给 useReducer 初始状态

reactjs - 在 map 函数中 react setState

javascript - 如何删除事件监听器,以便在卸载组件时它不会尝试更新状态?

javascript - react useEffect 和异步获取