Javascript 使用react回调ref和转发ref

Javascript 使用react回调ref和转发ref,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我有一个复选框react组件,它必须支持不确定状态,但我正在更新我们的组件以正确转发引用。复选框组件已经在内部使用回调引用来设置不确定属性。以下是原始组件(简化): 导出类型ICheckboxProps={ 选中?:布尔值 不确定?:布尔值 }&React.inputtmlattributes 导出常量复选框:React.FC=props=>{ const{checked=false,…rest}=props; 返回( { 如果(参考){ ref.indeterminate=!checked?i

我有一个复选框react组件,它必须支持不确定状态,但我正在更新我们的组件以正确转发引用。复选框组件已经在内部使用回调引用来设置不确定属性。以下是原始组件(简化):

导出类型ICheckboxProps={
选中?:布尔值
不确定?:布尔值
}&React.inputtmlattributes
导出常量复选框:React.FC=props=>{
const{checked=false,…rest}=props;
返回(
{
如果(参考){
ref.indeterminate=!checked?indeterminate!:false;
}
}}
{…休息}
/>
)
}
现在,因为这是一个UI库,所以我也尝试转发一个ref。但这与回调ref冲突-现在我有两个独立的ref。此外,转发的ref可能是回调ref。因此,我甚至无法访问那里的实例来设置不确定属性。我试过很多东西,但不管我做什么,打字脚本都会有用,红色下划线告诉我我错了

如何将转发的引用应用于输入并在输入上设置不确定属性

大部分情况如下,但有一个问题需要注意:

导出类型ICheckboxProps={
选中?:布尔值
不确定?:布尔值
}&React.inputtmlattributes
导出常量复选框=React.forwardRef((props,inRef)=>{
const{checked=false,…rest}=props;
返回(
{
如果(参考){
ref.indeterminate=!checked?indeterminate!:false;
如果(inRef){
if(inRef类型==“函数”){
inRef(参考)
}否则{
inRef.current=ref//无法分配给“current”,因为它是只读属性。
}
}
}
}}
{…休息}
/>
)
})

您可以对转发的ref执行任何操作,包括设置其当前值:

const Checkbox = React.forwardRef(({ checked = false, indeterminate, ...rest }, forwardedRef) => (
  <input
    type="checkbox"
    checked={checked}
    ref={(inputElement) => {
      if (inputElement) {
        inputElement.indeterminate = !checked && indeterminate
      }

      if (forwardedRef) {
        if(typeof(forwardedRef) !== "function") {
          forwardedRef(inputElement)
      } else {
        forwardedRef.current = inputElement
      }
    }
    {...rest}
  />
))
const Checkbox=React.forwardRef({checked=false,不确定,…rest},forwardedRef)=>(
{
if(输入元素){
inputElement.Undeterminate=!选中和不确定(&U)
}
if(forwardedRef){
if(typeof(forwardedRef)!=“函数”){
forwardedRef(inputElement)
}否则{
forwardedRef.current=inputElement
}
}
{…休息}
/>
))

使用命令句柄
钩子的作用与第二个示例几乎完全相同。
ref.current
inRef
的赋值由React在内部处理,您不必通过更改readonly属性来破坏契约

export const Checkbox=React.forwardRef((props,inRef)=>{
常量{checked=false,不确定,…rest}=props;
const ref=useRef(空)
使用命令句柄(inRef,()=>ref.current!,[ref])
返回(
)
})


我想对
ref.current
上的非空断言发表一点意见。据我所知,儿童的refs在父母的refs之前就已经解决了,但我在文档中找到的唯一相关语句是调用
inputRef.current.focus()

中没有空保护,这可以处理95%的情况,但理论上,转发引用也可能是回调引用。我想在这种情况下,如果(forwardedRef&&typeof(forwardedRef)==“function”)forwardedRef(inputElement)
,我可以做
,但是,我也有这个问题:“无法分配给“current”,因为它是只读属性。"啊,对了,我忘了。是的,我确实看不出有什么办法。React必须做类似的事情,因为它们接受REF和回调REF。编辑答案以确保完整性。关于TypeScript抱怨,我从未使用过TypeScript,但似乎有两种对象类型用于REF:这个问题很好地解释了这一点,您可能希望使用非re阿多利版本。