
最新在使用 react-dnd ,如下例子,useDrag 会返回一个 drag ,这个需要挂载到一个组件的 ref 上去 如果是一个 html element 或者 class component ,是有 ref 的,但是一个函数组件,是没有 ref 的,怎么挂上去呢?
export const Box = function Box({ name }) { const [{ isDragging }, drag] = useDrag(() => ({ type: ItemTypes.BOX, item: { name }, end: (item, monitor) => { const dropResult = monitor.getDropResult(); if (item && dropResult) { window.alert(`You dropped ${item.name} into ${dropResult.name}!`); } }, collect: mOnitor=> ({ isDragging: monitor.isDragging(), handlerId: monitor.getHandlerId() }) })); const opacity = isDragging ? 0.4 : 1; return ( <div ref={drag} style={{ ...styleBox, opacity }} data-testid={`box-${name}`} > {name} </div> ); }; 如果是个函数组件,比如,div 换成一个 function component ,drag 无法生效。 debug into react-dnd 的源代码,就会发现,找不到 drag source,因为 ref 一直是 null
export const Box = function Box({ name }) { const [{ isDragging }, drag] = useDrag(() => ({ type: ItemTypes.BOX, item: { name }, end: (item, monitor) => { const dropResult = monitor.getDropResult(); if (item && dropResult) { window.alert(`You dropped ${item.name} into ${dropResult.name}!`); } }, collect: mOnitor=> ({ isDragging: monitor.isDragging(), handlerId: monitor.getHandlerId() }) })); const opacity = isDragging ? 0.4 : 1; return ( <FunctionComponent ref={drag} style={{ ...styleBox, opacity }} data-testid={`box-${name}`} > {name} </FunctionComponent> ); }; 当然,这个 FunctionComponent 也是一个复杂组件,可能级联下去,孙子的孙子也是一个 div 元素。 但是怎么能够把 react-dnd 的的这个 drag ,传递给孙子的孙子的 div 元素 ref 元素呢?
谢谢!
1 GentleFifth 2022 年 1 月 28 日 via Android forwardRef |
2 momocraft 2022 年 1 月 28 日 这个 ref 应该设计目的是给 DOM element 的 (得到一个 class component 的 instance 没意义, 因为不知道把 event handler 挂到 DOM 的哪里去) 因此不管是 class comopnent 还是 FC, 你都可以通过一个不叫 ref 的 prop 传递 只要最终传到一个 DOM element 就行 |
3 yazoox OP |
4 Yukee798 2022 年 1 月 28 日 React.forwardRef 应该能解决你的问题,可以去看一下文档 https://react.docschina.org/docs/forwarding-refs.html |
5 GentleFifth 2022 年 1 月 28 日 via Android @yazoox 2 楼是对的,如果 FC 是第三方组件的话,建议外面包一层 div ,给 react-dnd 使用,forwardRef 可以给 FC 透传 ref |
6 momocraft 2022 年 1 月 28 日 如果这个 FC 无法以任何方式塞自己的 DOM element 进去 (包括 children 和各种 props) , 就套一层 div 好了 |
7 shilianmlxg 2022 年 1 月 28 日 听大佬们分析 学了好多东西 |
8 66beta 2022 年 1 月 28 日 你这组件没有 forwardRef 吧 |
9 yazoox OP |
11 KuroNekoFan 2022 年 2 月 11 日 一层一层传感觉好痛苦,这种我选择 context.... |