最新在使用 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-01-28 11:50:18 +08:00 via Android
forwardRef
|
2
momocraft 2022-01-28 11:58:10 +08:00
这个 ref 应该设计目的是给 DOM element 的 (得到一个 class component 的 instance 没意义, 因为不知道把 event handler 挂到 DOM 的哪里去)
因此不管是 class comopnent 还是 FC, 你都可以通过一个不叫 ref 的 prop 传递 只要最终传到一个 DOM element 就行 |
3
yazoox OP |
4
Yukee798 2022-01-28 12:12:27 +08:00
React.forwardRef 应该能解决你的问题,可以去看一下文档 https://react.docschina.org/docs/forwarding-refs.html
|
5
GentleFifth 2022-01-28 12:13:22 +08:00 via Android
@yazoox 2 楼是对的,如果 FC 是第三方组件的话,建议外面包一层 div ,给 react-dnd 使用,forwardRef 可以给 FC 透传 ref
|
6
momocraft 2022-01-28 12:31:33 +08:00
如果这个 FC 无法以任何方式塞自己的 DOM element 进去 (包括 children 和各种 props) , 就套一层 div 好了
|
7
shilianmlxg 2022-01-28 13:52:38 +08:00
听大佬们分析 学了好多东西
|
8
66beta 2022-01-28 13:53:52 +08:00
你这组件没有 forwardRef 吧
|
9
yazoox OP |
11
KuroNekoFan 2022-02-11 17:34:02 +08:00
一层一层传感觉好痛苦,这种我选择 context....
|