我曾经在我的组件渲染时有refs,它工作:
// props.children is ReactElement<HTMLDivElement>[]
const [childRefs] = useState<RefObject<any>[]>(props.children.map(() => createRef()));
// working code, all the variables (props, childRefs etc) are defined earlier in scope
return <div {...props}>
{
props.children.map((c, i) => <div key={i} ref={childRefs[i]}>{c}</div >)
}
</div>
基本上,我使用refs命令直接设置一些转换到样式,因为鼠标移动在JSmousemove
事件。
Layer
),它接受子元素,克隆它,设置CSS类,并返回它:
function Layer(props:LayerProps){
const elem = cloneElement(props.children, {...props.children.props,
className: styles['layer']
});
return elem;
}
我也像这样更新了主组件:
return <div {...props}>
{
props.children.map((c, i) => <Layer key={i} ref={childRefs[i]}>{c}</Layer>)
}
</div>
然而现在我的ref
现在没有通过,可以理解,因为Layer
功能组件不能有ref
(因为它是一个功能)。当我尝试将ref
设置为Layer
时,它不能,并且有这个错误(可以理解):
(property) ref: React.RefObject<any>
Type '{ children: ReactElement<HTMLDivElement, string | JSXElementConstructor<any>>; key: number; ref: RefObject<any>; }' is not assignable to type 'IntrinsicAttributes & LayerProps'.
Property 'ref' does not exist on type 'IntrinsicAttributes & LayerProps'.ts(2322)
如果我尝试使用forwardRef
转发ref
,它没有任何东西可以设置ref,因为我只是修改传递的子元素并返回它,而不是返回像<div>...</div>
这样的新元素,我可以转发像<div ref={forwardedRef}>...</div>
这样的ref。
如何修改CSS类和保持一个ref
的对象?我知道如何做每一个(如果我只需要添加类IcloneElement
,如果我只需要ref它,我使用forwardRef
,并将其传递给JSX的子组件),但我无法弄清楚能够同时做到这两个。
我该怎么做?
好了,经过一番挖掘和实验,我意识到我可以给ref
"prop"(这不是一个技术上真正的道具,但无论如何)在cloneElement
就像任何道具。
我最终转发ref到功能组件,并提供ref
作为新克隆元素的道具,它工作了。
然而,TypeScript定义错误地将ref
属性标记为不存在,而它可以完美地工作。我需要它将道具转换为any
以沉默linter错误:
const Layer = forwardRef((props:LayerProps, ref:any) => {
const elem = cloneElement(props.children, {
className: `${props.children.props.className ?? ''} ${styles['layer']}`,
ref: ref
} as any); // as any fixes ref complaining
return elem;
});
And in many component:
return <div {...props}>
{
props.children.map((c, i) => <Layer key={i} ref={childRefs[i]}>{c}</Layer>)
}
</div>