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
Android | iOS |
---|---|