https://github.com/kbanashek/rncardlist
React Native baseball card app built with Expo and React Relay
https://github.com/kbanashek/rncardlist
expo react-native react-relay typescript
Last synced: about 1 year ago
JSON representation
React Native baseball card app built with Expo and React Relay
- Host: GitHub
- URL: https://github.com/kbanashek/rncardlist
- Owner: kbanashek
- Created: 2025-03-12T15:35:38.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-03-12T18:24:28.000Z (about 1 year ago)
- Last Synced: 2025-03-12T18:34:30.846Z (about 1 year ago)
- Topics: expo, react-native, react-relay, typescript
- Language: TypeScript
- Homepage:
- Size: 4.38 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# RNCardList
A React Native app built with Expo and React Relay (against a mock service) for managing a collection of baseball cards. Users can view cards, see detailed information, and like their favorite cards.
## List Screen:

## Detail Screen:

## Screenshots
### Optimistic UI Updates
The like button demonstrates immediate feedback:
1. Heart icon changes instantly on tap
2. Loading indicator shows during request
3. Reverts on error (e.g., when offline)
## Features
- View list of baseball cards
- Card details view
- Like/unlike cards with instant feedback
- Optimistic UI updates
- Immediate UI response without waiting for server
- Smooth user experience for like/unlike actions
- Graceful error handling and state reversion
- Offline capabilities
- Image caching
## Tech Stack
- [React Native](https://reactnative.dev) - A framework for building native apps using React
- [Expo/EAS](https://expo.dev) - Platform and build service for React Native apps
- [React Relay](https://relay.dev) - Production-ready GraphQL client for React
- [TypeScript](https://www.typescriptlang.org) - JavaScript with syntax for types
- [React Navigation](https://reactnavigation.org) - Routing and navigation for React Native apps
- [React Native Paper](https://callstack.github.io/react-native-paper) - Material Design components for React Native
## Prerequisites
- [Node.js](https://nodejs.org) v18 or higher - JavaScript runtime environment
- [npm](https://www.npmjs.com) or [yarn](https://yarnpkg.com) - Package managers for Node.js
- [Expo CLI](https://docs.expo.dev/get-started/installation) - Command line tool for Expo development
- iOS Simulator (for iOS development)
- macOS - Required for iOS development
- Xcode (latest version) - iOS development environment
- Android Studio (for Android development)
- Android SDK - Software development kit for Android
- Android Emulator - Virtual device for testing Android apps
## Getting Started
1. Clone the repository:
```bash
git clone https://github.com/kbanashek/RNCardList.git
cd RNCardList
```
2. Install dependencies:
```bash
npm install
```
3. Start the development server:
```bash
npm start
```
4. Open the app:
- For iOS: Press `i` in the terminal or run `npm run ios`
- For Android: Press `a` in the terminal or run `npm run android`
5. Unit Tests
```bash
npm run test
```
## Development
The app uses a mock GraphQL service for data. All network requests are handled through Relay, with offline support and optimistic updates.
### Optimistic Updates
The app implements optimistic UI updates to provide instant feedback for user actions:
```typescript
// Example from useToggleCardLike hook
commit({
variables: { input: { cardId } },
// Update UI immediately
optimisticResponse: {
toggleCardLike: {
card: {
id: cardId,
isLiked: true,
},
},
},
// Revert UI if server request fails
onError: (error) => {
// Handle error state
},
});
```
This pattern:
1. Updates UI immediately when user takes action
2. Sends request to server in background
3. Handles errors by reverting UI if needed
#### Implementation Details
The optimistic updates are implemented using React Relay's mutation API:
1. **State Management**:
```typescript
const [state, setState] = useState({
loadingCardIds: new Set(), // Track loading state per card
error: null, // Handle errors globally
});
```
2. **Loading States**:
- Each card tracks its own loading state
- UI can show loading indicators while request is pending
- Prevents duplicate requests for the same card
3. **Error Handling**:
- Global error state for user feedback
- Automatic UI reversion on failure
- Proper cleanup of loading states
#### Component Integration
The `LikeButton` component integrates with the optimistic update system:
```typescript
const LikeButton = ({ cardId, isLiked }) => {
const { toggleLike, isLoading } = useToggleCardLike();
return (
toggleLike(cardId)}
disabled={isLoading}
// Show loading state while request is pending
loading={isLoading}
/>
);
};
```
#### Optimistic Updates
1. Enable network debugging in Chrome DevTools
2. Like a card and verify:
- UI updates immediately
- Network request is sent in background
- UI remains updated after request completes
3. Test error handling:
- Enable airplane mode
- Like a card
- Verify UI reverts when offline
#### Offline Testing
1. Load the app with network connection
2. Enable airplane mode
3. Verify:
- Cards are still visible
- Images load from cache
- Like/unlike actions show proper error states
- Network status banner appears
4. Re-enable network:
- Banner should disappear
- Any pending actions should resolve
### Architecture
#### Offline Support
The app uses several strategies to provide a seamless offline experience:
1. **Data Persistence**:
- Relay stores query data in memory cache
- Images are pre-cached on first load
- Network state is monitored via NetInfo
2. **UI Feedback**:
- Network status banner shows offline state
- Loading states indicate pending actions
- Error states show when actions fail
- Cached data is used when offline
3. **Error Recovery**:
- Automatic retry when network returns
- Clear error states on reconnection
- Preserve user actions when possible