Skip to content

Instantly share code, notes, and snippets.

View nandorojo's full-sized avatar

Fernando Rojo nandorojo

View GitHub Profile
@nandorojo
nandorojo / DraggableScrollView.tsx
Last active November 6, 2024 13:26
Make a horizontal `ScrollView` draggable with a mouse (`react-native-web`)
import React, { ComponentProps } from 'react'
import { ScrollView } from 'react-native'
import { useDraggableScroll } from './use-draggable-scroll'
export const DraggableScrollView = React.forwardRef<
ScrollView,
ComponentProps<typeof ScrollView>
>(function DraggableScrollView(props, ref) {
const { refs } = useDraggableScroll<ScrollView>({
outerRef: ref,
@nandorojo
nandorojo / rn-for-web.md
Last active November 5, 2024 16:32
I learned React Native as a web developer, and I got everything wrong

When I built my first React Native app, I had some prior web experience. Using React on iOS and Android felt like a natural way to apply my skills.

But I was suprised to learn, the hard way, that my web-developer-way-of-thinking didn't apply to native apps.

To understand why, let's start with the navigation layout. Each website has unique page primitives. The header at the top of the page, the sidebar menu, the footers – they're all hand-rolled.

You write a <header> and all you get is an empty box. You then use your own JavaScript and CSS to make it useful.

The way these elements look and feel is part of your brand. If your header looks just like another website, something feels off.

@nandorojo
nandorojo / xcrun-fix.md
Created November 5, 2024 16:23
Fix that xcrun simctl boot error from React Native iOS simulator

You just got this error after running npx expo run:ios or building React Native locally:

Error: xcrun simctl boot 62F02616-B3DF-4F78-9770-74AD88CB7DC2 exited with non-zero code: 60
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=60):
Unable to boot the Simulator.
launchd failed to respond.
Underlying error (domain=com.apple.SimLaunchHostService.RequestError, code=4):
        Failed to start launchd_sim: could not bind to session, launchd_sim may have crashed or quit responding
@nandorojo
nandorojo / knew.md
Last active November 4, 2024 17:18
What I wish I knew when I started with Expo Web, React Navigation & Next.js

I started using React Native in September 2018. I always forget some things when I build new apps, so I'll keep track of the gotchas on this post.

Some topics, such as navigation, will be fundamental to how I think about apps. Others, will be one-line helpers that make apps work more smoothly.

It's gotten to the point where I find my own answers from 6 months before on certain Github issues.

I'll keep adding over time as I think of more. If anyone thinks these topics would be useful, let me know and I'll elaborate.

I have made libraries to address a number of the topics here, from navigation to design.

@nandorojo
nandorojo / animate-height.tsx
Last active October 13, 2024 08:41
Moti Animate Height
import { StyleSheet } from 'react-native'
import Animated, {
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated'
import { AnimateHeightProps } from './index.types'
const transition = { duration: 200 } as const
@nandorojo
nandorojo / expo-fix.md
Created October 2, 2024 17:58
How to fix this common Expo iOS error

If you get this error running npx expo run:ios:

Error: xcrun simctl boot 62F02616-B3DF-4F78-9770-74AD88CB7DC2 exited with non-zero code: 60
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=60):
Unable to boot the Simulator.
launchd failed to respond.
Underlying error (domain=com.apple.SimLaunchHostService.RequestError, code=4):
        Failed to start launchd_sim: could not bind to session, launchd_sim may have crashed or quit responding
Error: xcrun simctl boot 62F02616-B3DF-4F78-9770-74AD88CB7DC2 exited with non-zero code: 60
@nandorojo
nandorojo / widget.md
Last active October 2, 2024 16:56
How to create an iOS Widget with React Native (Expo / EAS)

First, copy the config plugin from this repo: https://github.com/gaishimo/eas-widget-example

You can reference my PRs there too (which, at the time of writing, aren't merged).

After adding the config plugin (see app.json) with your dev team ID, as well as a bundle ID, you can edit the widget folder to edit your code. Then npx expo run:ios (or npx expo run:android).

Workflow

After npx expo run:ios, open the ios folder, and open the file that ends in .xcworkspace in XCode. Make sure you have the latest macOS and XCode versions. If you don't, everything will break.

@nandorojo
nandorojo / reanimated-shared-element-gallery.tsx
Created November 10, 2020 22:07
React Native Reanimated v2 Shared Element Transition Image Gallery
@nandorojo
nandorojo / private-npm-in-gh-actions.md
Created August 3, 2021 23:52
Use private NPM packages in your GitHub actions

1 NPM_TOKEN

Add an NPM_TOKEN secret on GitHub. Get your secret key from the NPM dashboard.

2 Add a step to your action

- name: Authenticate with private NPM package
  run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
@nandorojo
nandorojo / create-context.tsx
Last active September 21, 2024 19:51
A much better createContext, usable before React 19, with good TypeScript Types
import { createContext as create, useContext } from 'react'
export function createContext<T>(initial?: T) {
const ctx = create<T>(initial ?? (null as any))
return Object.assign(
function Provider(props: React.ComponentProps<typeof ctx.Provider>) {
return <ctx.Provider {...props} />
},
ctx,