6. Region selector
Let customers pick a region and persist it in the app.
On this page
In this step, you'll create a region selector component that allows users to select their country and currency. This is important for providing a localized shopping experience.
To implement this, you'll:
- Create a region context to manage the selected region state.
- Create a region selector component that allows users to choose their country and currency from a list.
- Update the app's navigation to add a drawer menu for the region selector.
Create Region Context
The region context will manage the selected region state and provide it to child components. You'll create a context, a provider component, and a custom hook to access the context.
To create the region context, create the file context/region-context.tsx with the following content:
tsx
You define the RegionContext with the following properties that child components can use:
regions: An array of available regions fetched from the Aiminaabee backend.selectedRegion: The currently selected region.selectedCountryCode: The country code of the selected country within the selected region. This is useful as regions can have multiple countries, and you'll allow customers to select their country.setSelectedRegion: A function to update the selected region and country code.loading: A boolean indicating whether the regions are being loaded.error: An error message if loading the regions fails.
You also define the RegionProvider component that will wrap the app and provide the region context to its children.
Next, you'll implement the logic to load the regions from the Aiminaabee backend, and manage the selected region state.
Replace the // TODO load and select regions comment with the following:
tsx
You define the loadRegions function that fetches the regions from the Aiminaabee backend using the JS SDK. It also loads any previously selected region and country from AsyncStorage, or defaults to the first region and its first country.
Then, you run the loadRegions function when the component mounts using the useEffect hook.
You also define the setSelectedRegion function that updates the selected region and country, and saves them to AsyncStorage.
Then, you provide the context values to child components using the RegionContext.Provider.
Finally, you'll create a custom hook in the same file to access the region context easily. Replace the // TODO add useRegion hook comment with the following:
tsx
You define the useRegion hook that retrieves the context value using useContext. It also throws an error if the hook is used by a component that is not wrapped in the RegionProvider.
Create Region Selector Component
Next, you'll create the region selector component that allows users to choose their country and currency.
To create the region selector component, create the file components/region-selector.tsx with the following content:
tsx
You define the RegionSelector component that receives an optional onRegionChange prop. This prop is a callback function that will be called when the user selects a new region.
In the component, you:
- Use the
useRegionhook to access all regions, the selected region and country, and the function to set the selected region. - Use the
useColorSchemehook to get the current color scheme and apply the appropriate colors. - Create a memoized list of countries by flattening the countries from all regions. Each country includes its associated region and currency code. The list is sorted alphabetically by country name.
Next, you'll implement the logic to handle country selection and render the list of countries. Replace the // TODO handle country selection comment with the following:
tsx
You define the handleSelectCountry function that is called when a user selects a country. It updates the selected region and country using the setSelectedRegion function from the context, and calls the onRegionChange callback if provided.
You also define the isCountrySelected function that checks if a given country is currently selected.
Finally, you render the countries in a scrollable view. For each country, you create a touchable item that displays the country name and currency code. The selected country is highlighted, and a checkmark is shown next to it.
Add Drawer Content Component
Next, you'll create a custom drawer content component that includes the region selector in the app's navigation drawer.
Create the file components/drawer-content.tsx with the following content:
tsx
The DrawerContent component receives the drawer navigation props. You render the RegionSelector component and pass an onRegionChange callback that closes the drawer when a region is selected.
Add Drawer Navigation
Finally, you'll update the app's navigation to wrap the main screens in a drawer navigator that uses the custom drawer content.
If you have an app/(tabs) directory for tab navigation, remove it for now. You'll add it later inside the drawer navigator.
Then, create the directory app/(drawer) which will contain the drawer navigation setup.
Next, create the file app/(drawer)/_layout.tsx with the following content:
tsx
The DrawerLayout component sets up the drawer navigator using Expo Router's Drawer component.
The custom drawer content is shown on the left side of the screen, and the header is hidden.
Later, you'll add the tab screens inside the drawer navigator.
Next, replace the content of the file app/_layout.tsx with the following:
tsx
The key changes are:
- Wrap the app in the
RegionProviderto provide the region context to all components. - Set the initial screen to the
(drawer)layout, which contains the drawer navigator.
Later, you'll add the checkout and order confirmation screens to the stack navigator.
You'll test the region selector after implementing the main screens of the app in the next steps.
Next: 7. Cart context