Ref转发

作者: 小冰山口 | 来源:发表于2024-01-13 16:01 被阅读0次

使用自定义组件, 外层操作原始组件:

当有这个一个场景:
比如我自定义了一个CustomTextInput, 如下图

image.png
整个红色部分都是我自定义的组件CustomTextInput
那么如果我想在外层, 比如得到焦点按钮和失去焦点按钮想去操作这个自定义组件内部的TextInput, 应该怎么做呢?
这个时候就要用到Ref转发
以前的代码是直接return一个函数:
() => {
    const [numberValue, setNumberValue] = useState<string>('')
    return (
      <View style={styles.root}>
        <View style={styles.backgroud}>
          <TextInput
            ref={ref} 
            style={styles.textInput}
            placeholder='请输入手机号码'
            placeholderTextColor={'#999999'}
            keyboardType='number-pad'
            value={numberValue}
            onChangeText={(value) => {
              setNumberValue(value)
            }}
          >
          </TextInput>
          <TouchableOpacity 
            style={styles.deleteButton}
            onPress={() => {
              setNumberValue('')
            }}
          >
            <Image 
              style={[styles.deleteButton]}
              source={icon_delete}
            >
            </Image>
          </TouchableOpacity>
        </View>
        { numberValue.length <= 0 ? 
          <View style={styles.statusView}>
            <Image 
              source={icon_question}
              style={styles.hintImg}
            ></Image>
            <Text style={[styles.hintTxt, styles.notInput]}>
              {`请输入手机号码`}
            </Text>
          </View> : numberValue.length === 11 ? 
          <View style={styles.statusView}>
            <Image 
              source={icon_right}
              style={styles.hintImg}
            ></Image>
            <Text style={[styles.hintTxt, styles.valid]}>
              {`输入正确`}
            </Text>
          </View> :
          <View style={styles.statusView}>
            <Image 
              source={icon_error}
              style={[styles.hintImg, styles.errorImg]}
            ></Image>
            <Text style={[styles.hintTxt, styles.invalid]}>
              {`手机号码格式错误`}
            </Text>
          </View>
        }
      </View>
    )
  }

那么现在, 这个函数需要用forwardRef包裹一下

export default forwardRef<TextInput, any>(
  (props, ref) => {
    const [numberValue, setNumberValue] = useState<string>('')
    return (
      <View style={styles.root}>
        <View style={styles.backgroud}>
          <TextInput
            ref={ref} 
            style={styles.textInput}
            placeholder='请输入手机号码'
            placeholderTextColor={'#999999'}
            keyboardType='number-pad'
            value={numberValue}
            onChangeText={(value) => {
              setNumberValue(value)
            }}
          >
          </TextInput>
          <TouchableOpacity 
            style={styles.deleteButton}
            onPress={() => {
              setNumberValue('')
            }}
          >
            <Image 
              style={[styles.deleteButton]}
              source={icon_delete}
            >
            </Image>
          </TouchableOpacity>
        </View>
        { numberValue.length <= 0 ? 
          <View style={styles.statusView}>
            <Image 
              source={icon_question}
              style={styles.hintImg}
            ></Image>
            <Text style={[styles.hintTxt, styles.notInput]}>
              {`请输入手机号码`}
            </Text>
          </View> : numberValue.length === 11 ? 
          <View style={styles.statusView}>
            <Image 
              source={icon_right}
              style={styles.hintImg}
            ></Image>
            <Text style={[styles.hintTxt, styles.valid]}>
              {`输入正确`}
            </Text>
          </View> :
          <View style={styles.statusView}>
            <Image 
              source={icon_error}
              style={[styles.hintImg, styles.errorImg]}
            ></Image>
            <Text style={[styles.hintTxt, styles.invalid]}>
              {`手机号码格式错误`}
            </Text>
          </View>
        }
      </View>
    )
  }
)

那么在外层的调用就非常简单了, 如下图


image.png

自定义组件对外暴露api

假设这样一个场景, 我在外层并不想直接操作TextInputref, 而是我想直接操作CustomTextInputref

  • 函数式组件实现方式
  1. 首先你要将接口暴露出来
export interface CustomInputRef {
  customBlur: () => void
  customFocus: () => void
}
  1. 你要实现这两个方法
    const inputRef = useRef<TextInput>(null)

    const customBlur = () => {
      inputRef.current?.blur()
    }

    const customFocus = () => {
      inputRef.current?.focus()
    }
  1. forwardRef的转发还是不变, 但泛型要去掉, 然后外面传进来的ref, 作为参数传入hook函数useImperativeHandle的第一个参数, 第二个参数是一个函数, 返回一个对象, 对象是将函数名返回出去.
    我的理解是, interface是返回函数名, 而useImperativeHandle是找到对应的函数实现.
    image.png
  • class组件实现方式
    虽然class组件很少用了, 但是还是要熟悉它是怎么在外层调用api

class组件是不需要转发的, 它是直接在外层能够调用到方法

image.png
区别在于, ref需要自己创建
inputRef = React.createRef<TextInput>()

使用时:


image.png

相关文章

  • 2021-02-05 React useImperativeHa

    使用函数时组件的时候,ref转发是必须要了解的概念 如上,简介明了的解释了ref转发的概念。但是,上面的 ref ...

  • 如何使用React Refs

    如何在React中利用ref以及ref转发,回调ref和HOC React Ref是有用的功能,可作为从父组件中引...

  • refs转发常见案例

    1、转发refs到DOM组件 ref 转发是一个可选特性,其允许某些组件接收 ref,并将其向下传递给子组件。这种...

  • React中React.forwardRef的使用方式

    一、众多周知可以forwardRef可以转发ref属性比如要在父组件中调用子组件中某个DOM节点或者组件的ref ...

  • React 中的转发ref

    在 React V16.3� 中react引入了: React.forward((props, ref) => R...

  • ref转发到DOM元素

    Vue 为DOM元素添加ref属性 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件...

  • react获取ref

    获取子组件的dom,参考官网ref转发或者父子组件、高阶组件文章

  • 高阶组件转发子组件ref

    参考链接:react高阶组件+ref转发的组合使用[https://www.cnblogs.com/llcdbk/...

  • React native ref 使用

    ref={(ref)=>{this.xxxxx = ref}}

  • React 'Refs'

    ref 有两种 ref 方式 ref = ''string" //string ref = {this.saveI...

网友评论

      本文标题:Ref转发

      本文链接:https://www.haomeiwen.com/subject/cdbfodtx.html