使用自定义组件, 外层操作原始组件:
当有这个一个场景:
比如我自定义了一个CustomTextInput
, 如下图
![](https://img.haomeiwen.com/i2868984/18577f099a730ed9.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>
)
}
)
那么在外层的调用就非常简单了, 如下图
![](https://img.haomeiwen.com/i2868984/881bfb4ca6dd3ebd.png)
自定义组件对外暴露api
假设这样一个场景, 我在外层并不想直接操作TextInput
的ref
, 而是我想直接操作CustomTextInput
的ref
- 函数式组件实现方式
- 首先你要将接口暴露出来
export interface CustomInputRef {
customBlur: () => void
customFocus: () => void
}
- 你要实现这两个方法
const inputRef = useRef<TextInput>(null)
const customBlur = () => {
inputRef.current?.blur()
}
const customFocus = () => {
inputRef.current?.focus()
}
-
forwardRef
的转发还是不变, 但泛型要去掉, 然后外面传进来的ref, 作为参数传入hook
函数useImperativeHandle
的第一个参数, 第二个参数是一个函数, 返回一个对象, 对象是将函数名返回出去.
我的理解是,interface
是返回函数名, 而useImperativeHandle
是找到对应的函数实现.
image.png
-
class
组件实现方式
虽然class
组件很少用了, 但是还是要熟悉它是怎么在外层调用api
的
class
组件是不需要转发的, 它是直接在外层能够调用到方法
![](https://img.haomeiwen.com/i2868984/ecbeb4cde4596444.png)
区别在于,
ref
需要自己创建
inputRef = React.createRef<TextInput>()
使用时:
![](https://img.haomeiwen.com/i2868984/eac0a732635615b7.png)
网友评论