Check demo gif
Expo project template with the following features:
- Full TypeScript integration
- Prettier and Eslint configured
- Light and Dark theme support with styled-components
- React Navigation with initial structure to get started
- Storybook integrated with components and screens
- Hygen for generating new components and screens
- @testing-library/react-native with testing examples
- i18n integration
- React Query with initial data structure and examples integrated with Rick and Morty API
- Initial components structure integrated with storybook
- Initial screens structure integrated with storybook and tests
npx create-expo-app --template @rocali/expo-ts-rest-template my-app
- start
yarn start
- run on web
yarn web
- run on ios
yarn ios
- run on android
yarn android
- compile typescript
yarn ts
- lint
yarn lf
- run tests
yarn t
- ci (lint, typescript and tests)
yarn ci
- create new component
yarn new-comp NAME
- create new screen
yarn new-screen NAME
- add screen or component to storybook
yarn sbl
Run yarn new-comp NAME
to create component files
Run yarn sbl
to add the new componente to Storybook
Creating a new component generates
src/components/NAME/index.stories.tsx
src/components/NAME/index.tsx
The component structure is based on src/components/Base component We're using Hygen for generating the files and you can modify as you want on _templates/components/new
src/context
folder is used mostly exporting all Providers you need in the app
The exported AppProviders
is linked on src/index.tsx
src/data
is used to centralize all data related structure
The template comes with examples integrated with Rick and Morty API
For integrating the API data with Typescript we need to defined API all data types, so we devide the data info on:
Define all data model types
For example on /api/character
request it returns a list of Character
and we define the Character
types on src/data/models/character.ts
export interface Character {
id: number;
name: string;
...
}
Define the requests functions
For example on /api/character
request we define the typed function request on src/data/operations/characters.ts
integrating with the axiosInstance
exported on src/data/api.ts
and defining the request variables CharactersVars
and the request response CharactersData
integrated with the Character
data model from src/data/models/character
import { axiosInstance, PaginatedResponse } from '../api';
import { Character } from '../models/character';
//getCharacters
export interface CharactersVars {
page: number;
}
export type CharactersData = PaginatedResponse<Character>;
export async function getCharacters({
page,
}: CharactersVars): Promise<CharactersData> {
const { data } = await axiosInstance.get<CharactersData>(
`/character/?page=${page}`,
);
return data;
}
We're using React Query for data fecthing
React Query is often described as the missing data-fetching library for React, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your React applications a breeze.
React query exports useQuery
and useMutaion
hooks, and we define those typed hooks on src/data/hooks
For /api/character
request example we export a useCharactersQuery
on src/data/hooks/character
so when data
response from useCharactersQuery
already defines as CharactersData
type
import { AxiosError } from 'axios';
import {
useQuery,
UseQueryOptions,
} from 'react-query';
import {
getCharacters,
CharactersData
} from '../operations/characters';
//useCharactersQuery
type CharactersQueryOptions = {
options?: Omit<
UseQueryOptions<CharactersData, AxiosError>,
'queryKey' | 'queryFn'
>;
};
export function useCharactersQuery({
options
}: CharactersQueryOptions) {
return useQuery(
['characters'],
getCharacters
options,
);
}