React.forwardRef 与useImperativeHandle结合使用,就能调用方法组件内的方法,
import _ from 'lodash';
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
import Colors from '../constants/Colors';
import { Tools } from '../utils';
import { UIButton } from './UIButton';
import UIText from './UIText';
export const VerifyCodeView = React.forwardRef(({
codeLength = 6,
submitAction,
style,
codeStyle,
keyboardType,
onChange,
value,
continuously,
}, ref) => {
const [verifyCode, setVerifyCode] = useState(value ? value : '');
const inputRef = useRef();
const codeList = _.fill(Array(codeLength), '');
focus = () => {
const isFocused = inputRef.current.isFocused();
if (!isFocused) {
inputRef.current.focus();
}
};
useEffect(() => {
setVerifyCode(value ? value : '');
}, [value]);
useImperativeHandle(ref, () => ({//第一个参数:暴露哪个ref;第二个参数:暴露什么
clearValue: () => {
inputRef.current.clear();
setVerifyCode('');
}
}));
return (
<View
style={{ flexDirection: 'row', marginTop: 24, marginLeft: 16, ...style }}>
{codeList.map((text, index) => {
const code =
verifyCode && index <= verifyCode.length - 1 ? verifyCode[index] : '';
return (
<UIButton
key={index}
onPress={() => focus()}
style={{
borderColor: Tools.isEmptyStr(code)
? Colors.gray_EBEBEB
: Colors.black_1A1A1A,
borderWidth: 0.5,
borderLeftWidth: continuously ? (index == 0 ? 0.5 : 0) : 0.5,
height: 40,
width: 40,
borderRadius: 1,
marginRight: 12,
alignItems: 'center',
justifyContent: 'center',
...codeStyle,
}}>
<UIText
children={code}
style={{ fontSize: 24, color: Colors.black_1A1A1A }}
/>
</UIButton>
);
})}
<TextInput
ref={inputRef}
style={{ opacity: 0, ...StyleSheet.absoluteFillObject }}
onChangeText={text => {
if (onChange) {
onChange();
setVerifyCode(text);
if (text.length >= codeLength) {
inputRef && inputRef.current.blur();
submitAction && submitAction(text);
}
} else {
const reg = /^[0-9]*$/;
if (reg.test(text)) {
setVerifyCode(text);
if (text.length >= codeLength) {
inputRef && inputRef.current.blur();
submitAction && submitAction(text);
}
}
}
}}
value={`${verifyCode}`}
maxLength={codeLength}
caretHidden={true}
autoFocus={true}
keyboardType={keyboardType ? keyboardType : 'numeric'}
/>
</View>
);
})
父组件的调用方法如下:
if (this.inputRef.current) {
this.inputRef.current.clearValue();
}
<VerifyCodeView
ref={this.inputRef}
submitAction={(text) => {
this.bindPhone(text)
}} />
网友评论