【问题标题】:How do I assign ref to each element rendered by array mapping and how do I reference them如何将 ref 分配给数组映射呈现的每个元素以及如何引用它们
【发布时间】:2020-10-04 18:43:36
【问题描述】:

我需要什么:我需要为每个 div 分配特定的引用,这样我就可以检测到每个特定输入字段之外的点击,但是由于这些项目是通过映射呈现的,所有 div 具有相同的引用。例如,当我单击 item2 的 div 时,它会检测到它是 ref,因此它不会触发警报。

const ref = useRef(null)

const handleClickOutside = (e) => {
    if (ref.current && !ref.current.contains(e.target)) {
      alert('clicked')
    }
}

useEffect(() => {
    document.addEventListener('click', handleClickOutside, true)

    return () => {  
      document.removeEventListener('click', handleClickOutside, true)
    }
})


myList = ['item1', 'item2', 'item3']

myList.map(item => {
    return (
      <div key={item._id} ref={ref}>
        <input type="text" value={item.value} />
      </div>
    )
}

myList 代表我的状态并且是动态的

【问题讨论】:

    标签: reactjs dom ref


    【解决方案1】:

    将引用初始化为数组,并为每个索引分配相关引用。

    const listRef = useRef([]);
    
    myList.map((item, i) => {
      return (
        <div key={item._id} ref={(ref) => (listRef.current[i] = ref)}>
          <input type="text" value={item.value} />
        </div>
      );
    });
    
    // Now each array entry contains a reference to `div` element.
    // access the reference through index.
    listRef.current[i].contains(e.target);
    

    奖励:这是useOnClickOutside 自定义钩子实现的示例:

    import { useEffect } from 'react';
    
    function useOnClickOutside(ref, handler) {
      useEffect(
        () => {
          const listener = event => {
            // Do nothing if clicking ref's element or descendent elements
            if (!ref.current || ref.current.contains(event.target)) {
              return;
            }
            handler(event);
          };
    
          document.addEventListener(`mousedown`, listener);
          document.addEventListener(`touchstart`, listener);
    
          return () => {
            document.removeEventListener(`mousedown`, listener);
            document.removeEventListener(`touchstart`, listener);
          };
        },
    
        // Add ref and handler to effect dependencies
        // It's worth noting that because passed in handler is a new ...
        // ... function on every render that will cause this effect ...
        // ... callback/cleanup to run every render. It's not a big deal ...
        // ... but to optimize you can wrap handler in useCallback before ...
        // ... passing it into this hook.
    
        [ref, handler],
      );
    }
    
    export default useOnClickOutside;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      相关资源
      最近更新 更多