使用自定义组件, 外层操作原始组件:
当有这个一个场景:
比如我自定义了一个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
假设这样一个场景, 我在外层并不想直接操作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组件是不需要转发的, 它是直接在外层能够调用到方法
image.png
区别在于,
ref需要自己创建
inputRef = React.createRef<TextInput>()
使用时:
image.png







网友评论