Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应钩子:为列表记忆单击处理程序?_Reactjs_React Hooks - Fatal编程技术网

Reactjs 反应钩子:为列表记忆单击处理程序?

Reactjs 反应钩子:为列表记忆单击处理程序?,reactjs,react-hooks,Reactjs,React Hooks,我试图呈现一个项目列表,每个项目都有一个按钮,按下按钮时会切换下拉菜单 我的代码看起来像: function ItemList({items}) { const [isDropdownExpanded, setIsDropdownExpanded] = useState(null); const itemClickHandlers = useMemo(() => { const handlers = {} items.forEach(item => {

我试图呈现一个项目列表,每个项目都有一个按钮,按下按钮时会切换下拉菜单

我的代码看起来像:

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>
);
函数项列表({items}){
常量[isDropdownExpanded,setIsDropdownExpanded]=useState(null);
const itemClickHandlers=useMoom(()=>{
常量处理程序={}
items.forEach(item=>{
处理程序[item.id]=value=>setIsDropdownExpanded(value?item.id:null);
});
返回处理程序;
},[items.map(item=>item.id.join(','));
}
返回(
    {items.map(item=>
  • )}
);
上面的代码可以工作,但在用户从列表中添加或删除项目时会浪费渲染。(
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>
    );
}
函数项列表({items}){
常量[isDropdownExpanded,setIsDropdownExpanded]=useState(null);
const itemClickHandlers=useCallback((e)=>{
const id=e.currentTarget.id;
setIsDropdownExpanded(prev=>(prev!=id?id:null));
}, [])
返回(
    {items.map(item=>
  • )}
); }