I have an issue with focusing the next input in React Native. I use just one input called GeneralTextInput.tsx in the whole app.
In this example I have 2 inputs ==> 1.Group Name, 2.Group Description
So I give some props in the parent to this component:
JavaScript
x
48
48
1
<View style={classes.formContainer}>
2
<Text style={classes.label}>{t("group.name-your-group")}</Text>
3
4
<GeneralTextInput
5
width={"100%"}
6
returnKeyType={"next"}
7
isDoneReference={false}
8
deleteIcon
9
startIcon={"account-multiple"}
10
bordered={true}
11
placeholder={t("form.placeholders.groupName")}
12
value={props.newGroupName}
13
onChange={(val: string) => {
14
props.setNewGroupName(val);
15
if (val.length > 25) {
16
props.setNewGroupNameError(t("form.validations.max-25-char"));
17
}
18
if (val.length <= 25) {
19
props.setNewGroupNameError(undefined);
20
}
21
}}
22
/>
23
24
<Text style={classes.label}>{t("group.describe-your-group")}</Text>
25
26
<GeneralTextInput
27
width={"100%"}
28
returnKeyType={"done"}
29
isDoneReference={true}
30
isDismissed={true}
31
startIcon={"text"}
32
bordered={true}
33
isMultiLine={true}
34
numberOfLines={3}
35
placeholder={t("form.placeholders.groupDescription")}
36
value={props.newGroupDescription}
37
onChange={(val: string) => {
38
props.setNewGroupDescription(val);
39
if (val.length > 30) {
40
props.setNewGroupDescriptionError(t("form.validations.max-30-char"));
41
}
42
if (val.length < 30) {
43
props.setNewGroupDescriptionError(undefined);
44
}
45
}}
46
/>
47
</View>
48
And this is my GeneralTextInput.tsx What should I give to the input as a ref and how should I focus on it?
JavaScript
1
108
108
1
import * as React from "react";
2
import {
3
NativeSyntheticEvent,
4
Platform,
5
StyleProp,
6
TextInputFocusEventData,
7
TextStyle,
8
View,
9
ViewStyle,
10
TextInput,
11
ImageStyle,
12
Pressable,
13
} from "react-native";
14
import { makeStyles, IStyledComponent } from "../../assets/theme/installation";
15
import { IconButton, Text, useTheme } from "react-native-paper";
16
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
17
import FontAwesome5Icon from "react-native-vector-icons/FontAwesome5";
18
import { theme } from "../../assets/theme/DefaultTheme";
19
import { TouchableWithoutFeedback } from "react-native-gesture-handler";
20
21
export interface IGeneralTextInputProps
22
extends IStyledComponent<GeneralTextInputStyles> {
23
readonly value: string | undefined;
24
readonly placeholder?: string;
25
readonly onChange: (newValue: string) => void;
26
readonly onBlur?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
27
readonly isPassword?: boolean;
28
readonly autoCapitalize?: boolean;
29
readonly error?: string;
30
readonly startIcon?: string;
31
readonly startIconFA5?: string;
32
readonly endIcon?: string;
33
readonly deleteIcon?: boolean;
34
readonly disabled?: boolean;
35
readonly disabledInputText?: boolean;
36
readonly bordered?: boolean;
37
readonly isMultiLine?: boolean;
38
readonly width?: number | string;
39
readonly numberOfLines?: number;
40
readonly keyboardType?: string;
41
readonly isGratitude?: boolean;
42
readonly autoCorrect?: boolean;
43
readonly selectedMeasureUnit?: string;
44
readonly returnKeyType?: string;
45
readonly isDoneReference?: boolean;
46
readonly isDismissed?: boolean;
47
}
48
49
export const GeneralTextInput: React.FC<IGeneralTextInputProps> = (
50
props: IGeneralTextInputProps,
51
) => {
52
const classes = useStyles(props);
53
const { fonts, colors } = useTheme();
54
const [isPressed, setIsPressed] = React.useState(false);
55
const [isPasswordVisible, setPasswordVisible] = React.useState(false);
56
57
const groupNameRef = React.useRef<HTMLInputElement>(null);
58
const groupDescRef = React.useRef<HTMLInputElement>(null);
59
60
return (
61
<View style={classes.container}>
62
<TouchableWithoutFeedback>
63
<View style={classes.root}>
64
<TextInput
65
ref={() => (props.isDoneReference ? groupDescRef : groupNameRef)}
66
onSubmitEditing={() => {
67
groupDescRef.current?.focus();
68
}}
69
blurOnSubmit={props.isDoneReference ? true : false}
70
keyboardType={
71
props.keyboardType === "numpad" ? "numeric" : "default"
72
}
73
autoCorrect={props.autoCorrect}
74
multiline={props.isMultiLine}
75
numberOfLines={props.numberOfLines}
76
maxLength={props.isGratitude ? 300 : 50}
77
editable={!props.disabled}
78
onBlur={props.onBlur}
79
autoCapitalize={
80
props.autoCapitalize != undefined ? "words" : "none"
81
}
82
secureTextEntry={
83
props.isPassword == undefined ? false : !isPasswordVisible
84
}
85
style={
86
props.disabledInputText
87
? classes.disabledTextInput
88
: classes.textInput
89
}
90
value={props.value}
91
placeholder={props.placeholder}
92
placeholderTextColor={fonts.text.small.color}
93
onTouchEnd={() => setIsPressed(true)}
94
onChangeText={(value) => props.onChange(value)}
95
returnKeyType={
96
props.returnKeyType === "next"
97
? "next"
98
: props.returnKeyType === "done"
99
? "done"
100
: "default"
101
}
102
/>
103
</View>
104
</TouchableWithoutFeedback>
105
</View>
106
);
107
};
108
Advertisement
Answer
You wrap GeneralTextInput with forwardRef:
JavaScript
1
20
20
1
import { TextInput, TextInputProps } from "react-native";
2
3
4
export const GeneralTextInput: React.forwardRef<TextInput,IGeneralTextInputProps> = (
5
// type of props and ref will be inferred by ts
6
props
7
ref
8
) => {
9
.
10
return (
11
.
12
<TextInput
13
ref={ref}
14
{props}
15
16
17
18
/>
19
)}
20
Now in the parent component Define one useRef:
JavaScript
1
2
1
const secondInputRef = useRef<TextInput | null>(null);
2
you have 2 generalInput. on first input
JavaScript
1
9
1
<GeneralTextInput
2
.
3
.
4
// add this. this will focus on secondInput
5
onSubmitEditing={() => {
6
secondInputRef.current?.focus();
7
}}
8
/>
9
second GeneralInput will be as it is