Skip to main content

Text input

Unlike the on the web, there is no form component in React Native, the inputs are all handled individually.

The input used to receive text from the user's keyboard ia a TextInput. Despite the name, we use it for both text and numerical inputs.

The other thing we need to deal with here is the Keyboard. The keyboard will appear automatically when the text input is focused, but we can also close and open it programmatically.

The type of keyboard shown is actually determined by a prop on the TextInput: e.g. setting the keyboardType to phone-pad opens a keyboard that's laid out for entering phone numbers.

The closest equivalent to onSubmit on forms is the onSubmitEditing callback. Fired when the user presses the "return" key on their keyboard which in turn can be customized with the returnKeyType prop.

useState hook for shopping list

Start by creating a useState hook to store the shopping list and use an array.map to render all our items. Let's make it an array of objects with a name and an id.

Update: app/index.tsx
 import { StyleSheet, View } from "react-native";
import { theme } from "../theme";
import { ShoppingListItem } from "../components/ShoppingListItem";
+import { useState } from "react";
+
+type ShoppingListItemType = {
+ id: string;
+ name: string;
+};
+
+const initialList: ShoppingListItemType[] = [
+ { id: "1", name: "Coffee" },
+ { id: "2", name: "Tea" },
+ { id: "3", name: "Milk" },
+];

export default function App() {
+ const [shoppingList] = useState(initialList);
+
return (
<View style={styles.container}>
- <ShoppingListItem name="Coffee" />
- <ShoppingListItem name="Tea" isCompleted />
- <ShoppingListItem name="Milk" isCompleted />
+ {shoppingList.map((item) => (
+ <ShoppingListItem name={item.name} key={item.id} />
+ ))}
</View>
);
}

Add a TextInput

Now let's add another useState to store the current value of the TextInput, and render the text input at the top of the shopping list.

Update: app/index.tsx
@@ -1,4 +1,4 @@
-import { StyleSheet, View } from "react-native";
+import { StyleSheet, TextInput, View } from "react-native";
import { theme } from "../theme";
import { ShoppingListItem } from "../components/ShoppingListItem";
import { useState } from "react";
@@ -16,9 +16,16 @@ const initialList: ShoppingListItemType[] = [

export default function App() {
const [shoppingList] = useState(initialList);
+ const [value, setValue] = useState<string>();

return (
<View style={styles.container}>
+ <TextInput
+ value={value}
+ style={styles.textInput}
+ onChangeText={setValue}
+ placeholder="E.g Coffee"
+ />
{shoppingList.map((item) => (
<ShoppingListItem name={item.name} key={item.id} />
))}
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.colorWhite,
- justifyContent: "center",
+ paddingTop: 12,
+ },
+ textInput: {
+ borderColor: theme.colorLightGrey,
+ borderWidth: 2,
+ padding: 12,
+ fontSize: 18,
+ borderRadius: 50,
+ marginHorizontal: 12,
+ marginBottom: 12,
},
});

Now we'll want to use the onSubmitEditing callback to add the new shopping list item to the top of the list and clear the input.

Update: app/index.tsx
@@ -15,9 +15,20 @@ const initialList: ShoppingListItemType[] = [
];

export default function App() {
- const [shoppingList] = useState(initialList);
+ const [shoppingList, setShoppingList] = useState(initialList);
const [value, setValue] = useState<string>();

+ const handleSubmit = () => {
+ if (value) {
+ const newShoppingList = [
+ { id: new Date().toISOString(), name: value },
+ ...shoppingList,
+ ];
+ setShoppingList(newShoppingList);
+ setValue(undefined);
+ }
+ };
+
return (
<View style={styles.container}>
<TextInput
@@ -25,6 +36,8 @@ export default function App() {
style={styles.textInput}
onChangeText={setValue}
placeholder="E.g Coffee"
+ onSubmitEditing={handleSubmit}
+ returnKeyType="done"
/>
{shoppingList.map((item) => (
<ShoppingListItem name={item.name} key={item.id} />

Checkpoint

AndroidiOS
Checkpoint