Skip to main content

Props and useCallback

Recall that we can pass props down to child components, e.g.

<User name="Mary">
type UserProps = {  name: string;};
const User: React.FC<UserProps> = ({ name }) => {  return <Text>{name}</Text>;};

And useCallback is a react hook for memoizing interactions within a React component.

When we save our mood options, we'll want to also record their timestamp. Let's create a new type for the mood option with the timestamp. Open types.ts and add:

src/types.ts
export type MoodOptionWithTimestamp = {  mood: MoodOptionType;  timestamp: number;};

Now open Home.screen.tsx and add a useState variable to store out moodList:

src/screens/Home.screen.tsx
import { MoodOptionType, MoodOptionWithTimestamp } from '../types';const [moodList, setMoodList] = React.useState<MoodOptionWithTimestamp[]>([]);

Next, we'll add a useCallback that takes a mood option, adds a timestamp to it and appends it to the list of moods:

src/screens/Home.screen.tsx
const handleSelectMood = React.useCallback((mood: MoodOptionType) => {  setMoodList((current) => [...current, { mood, timestamp: Date.now() }]);}, []);

Now let's pass it the callback as a prop to the MoodPicker component:

src/screens/Home.screen.tsx
<MoodPicker onSelect={handleSelectMood} />

In the MoodPicker component, let's add a type for the new prop:

src/components/MoodPicker.tsx
type MoodPickerProps = {  onSelect: (mood: MoodOptionType) => void;};
export const MoodPicker: React.FC<MoodPickerProps> = ({ onSelect }) => {

And let's create a callback function that adds the calls onSelect with the currently selected mood:

src/components/MoodPicker.tsx
const handleSelect = React.useCallback(() => {  if (selectedMood) {    onSelect(selectedMood);    setSelectedMood(undefined);  }}, [onSelect, selectedMood]);

And let's call it onPress on the "Choose" button:

src/components/MoodPicker.tsx
<Pressable style={styles.button} onPress={handleSelect}>

Now back in Home.screen.tsx, we'll also want to list out the current mood list:

src/screens/Home.screen.tsx
<View style={styles.container}>  <MoodPicker onSelect={handleSelectMood} />+  {moodList.map((item) => (+    <Text key={item.timestamp}>+     {item.mood.emoji} {new Date(item.timestamp).toString()}+    </Text>+  ))}</View>
iOS mood listAndroid mood list