Giter VIP home page Giter VIP logo

expo-next-monorepo-example's Introduction

expo-next-monorepo-example's People

Contributors

axeldelafosse avatar nandorojo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

expo-next-monorepo-example's Issues

Is server side rendering possible?

Hi. Thanks for creating this monorepo.

I wonder whether server side rendering is possible here? I tried the example but couldn't get the SSR working.

Delete yarn.lock and then run yarn install. The next.js would fail to run...

Reproduce:

  1. Download the repo
  2. Delete yarn.lock
  3. run yarn
  4. run the next app, i.e. yarn dev:next

I got the following error:

info  - automatically enabled Fast Refresh for 1 custom loader
info  - Using external babel configuration from /.../packages/next/.babelrc.json
info  - automatically enabled Fast Refresh for 1 custom loader
HookWebpackError: Cannot read properties of undefined (reading 'replace')
    at makeWebpackError (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:41664:9)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25354:12
    at eval (eval at create (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140346:10), <anonymous>:12:1)
    at fn (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:22775:17)
    at Hook.eval [as callAsync] (eval at create (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140346:10), <anonymous>:10:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140148:14)
    at cont (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25351:34)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25399:10
    at symbolIterator (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:14443)
    at done (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:14823)
-- inner error --
TypeError: Cannot read properties of undefined (reading 'replace')
    at PagesManifestPlugin.createAssets (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.js:35:47)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.js:47:22
    at fn (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:22773:10)
    at Hook.eval [as callAsync] (eval at create (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140346:10), <anonymous>:10:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140148:14)
    at cont (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25351:34)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25399:10
    at symbolIterator (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:14443)
    at done (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:14823)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:9429
caused by plugins in Compilation.hooks.processAssets
TypeError: Cannot read properties of undefined (reading 'replace')
    at PagesManifestPlugin.createAssets (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.js:35:47)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.js:47:22
    at fn (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:22773:10)
    at Hook.eval [as callAsync] (eval at create (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140346:10), <anonymous>:10:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:140148:14)
    at cont (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25351:34)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/webpack/bundle5.js:25399:10
    at symbolIterator (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:14443)
    at done (/Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:14823)
    at /Users/yanzhu/Documents/Project/study/js/playgrounds/test/node_modules/next/dist/compiled/neo-async/async.js:1:9429

PS: The line info - automatically enabled Fast Refresh for 1 custom loader has come out twice...

What could be wrong here?

Expo with bare workflow

Could you tell me the best way to integrate an application created with Expo + Bare Workflow in monorepo Lerna or NX?

Using NextJS API Routes

Hey, this may not be the best place to ask this but I am wondering how you guys (@axeldelafosse & @nandorojo) would recommend integrating NextJS API routes?

I have been adapting my NextJS PWA over to expo using this repo as a template. I used SWR originally so a lot of my data fetches look like:

  const { data: positions, error } = useSWR<Position[]>(
    user?.token && user?.accountId
      ? ["/api/positions", user.token, user.accountId]
      : null, 
      fetcher
  )
}

I want to maintain this as best as possible and allow both the expo app & next site to use these endpoints.

I am now using swr-react-native for data fetching.

I have a few (non-elegant) ideas about how to go about this, but thought it best to ask if you had any thoughts on how best to approach it?

Add a license?

Thanks for a great resource here! Curious if you're open to adding a license so I can understand the copyright restrictions of using parts of this code / approach.

Thanks!

Better app.config.ts

Hi @axeldelafosse,

before I went ahead to create a PR, I would like to know if we're on the same page.
Since this package is using app.config.js, we don't have the magic Intellisense automatically using a VSCode plugin. But what can be done is:

  • Rename app.config.js to app.config.ts
  • Update package.json inside packages/expo and change main from index.js to index.ts
  • Rename packages/expo/index.js to index.ts

Change contents like so:

import { ExpoConfig } from '@expo/config-types';

declare var process: {
  env: {
    STAGE: "development" | "staging" | "production",
    SCHEME: string,
  }
}

const STAGE = process.env.STAGE;
const SCHEME = process.env.SCHEME ?? 'aaa.bbb.ccc';

const envConfig = {
  development: {
    scheme: `${SCHEME}.development`,
    icon: './assets/icon.development.png',
    backgroundColor: '#FF0000'
  },
  staging: {
    scheme: `${SCHEME}.staging`,
    icon: './assets/icon.staging.png',
    backgroundColor: '#8000FF'
  },
  production: {
    scheme: SCHEME,
    icon: './assets/icon.png',
    backgroundColor: '#1610FF'
  }
};

const stageConfig = envConfig[STAGE ?? 'development'];

const config: ExpoConfig = {
.....
  • Named export
  • A bit more semantic
  • And IntelliSense powered by Expo Config-Types

What do you think?

`as` path doesn't work properly (or does it?)

It seems that router.on('routeChangeComplete', path => ...) returns the asPath for the path argument. I need to clarify this still. But I'm trying to do something like this: router.push('/dashboard/my-artists/djkhaled', '/@djkhaled') where the URL should show the asPath /@djhkhaled.

However, it seems that the LinkTo component is trying to navigate to /@djkhaled instead of the href. This is breaking for me on Web, since my React Navigation linking config expects the more normal URL. So I'm going to look more into this.

It's possible we read from the Router directly inside of the routeChangeComplete event, since I would assume that that's all it's passing down to us anyway.

However, what is the desired behavior? Do we want React Navigation reading the as path, or the href? I think it should be the href, since that lets us use the correct URLs for navigating within a specific tab, etc.

Discussion

This isn't a bug, but rather a discussion over desired behavior. I think React Navigation should deal with the normal paths, rather than asPaths.

However, this wouldn't work for native deep linking.

In my case, I have a rewrite in Next.js. Any URL to /@:slug โ†’ /artists/[slug].

However, for deep linking into an app, if I send you beatgig.com/@djkhaled on like iMessage, and you open it from your phone, the native app will handle that as /@djkhaled, so we'd have to rewrite this here as well, presumably inside of getPathFromState. ๐Ÿฅฒ

Remix.run integration as alternative to Next?

Hi All,

Amazing work so far, massive fan of this repo!

Remix being the new SSR framework from the guys who made React Router (Its pretty amazing).

www.remix.run <----------- pure awesomness

Just throwing this out there to hear your thoughts, do you think a Nextjs could be easily swapped out in favour of using Remix in this monorepo, would we be able to use shared screens?

Thanks for any help on this :)

๐Ÿ˜„

Icons & Images don't work...

I spent the weekend testing the repository creating a responsive navigation, but I ran into a problem with Icons and Images.

Trying with Expo Vector Icons and React Native's Image Component. In the Expo mobile application, the icon appears perfectly, however in NextJS when my navigation is rendered, the icon or image does not appear.

I would like to understand what happens and if possible a tip on how I can create an image component to be used in both NextJS and Expo, both for icons in menus and for the rest of the application.

This application I'm making is a study only, I was interested in the repository and would like to see how it can be applied to my workflow.

NextJS Screenshot React Navigation:
NextJS Screenshot

Expo Screenshot React Navigation:
Expo Screenshot

ReferenceError: requestAnimationFrame is not defined

I'm having this problem. I believe it's trying to load in the server side, that's why the error, but not sure how to solve it:

ReferenceError: requestAnimationFrame is not defined
    at eval (webpack-internal:///../../node_modules/react-native-reanimated/lib/reanimated1/core/AnimatedNode.js:94:117)
    at Object.../../node_modules/react-native-reanimated/lib/reanimated1/core/AnimatedNode.js (/home/daniel/projects/labook/packages/web/.next/server/pages/_app.js:2050:1)
    at __webpack_require__ (/home/daniel/projects/labook/packages/web/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///../../node_modules/react-native-reanimated/lib/reanimated1/core/AnimatedEvent.js:16:71)
    at Object.../../node_modules/react-native-reanimated/lib/reanimated1/core/AnimatedEvent.js (/home/daniel/projects/labook/packages/web/.next/server/pages/_app.js:2028:1)
    at __webpack_require__ (/home/daniel/projects/labook/packages/web/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///../../node_modules/react-native-reanimated/lib/createAnimatedComponent.js:18:89)
    at Object.../../node_modules/react-native-reanimated/lib/createAnimatedComponent.js (/home/daniel/projects/labook/packages/web/.next/server/pages/_app.js:1797:1)
    at __webpack_require__ (/home/daniel/projects/labook/packages/web/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///../../node_modules/react-native-reanimated/lib/Animated.js:7:82)

Don't use the same screen `name` in multiple stacks

Sometimes, you want to reuse the same screen inside of different pages. For example, you might have /dashboard/user/artists/[slug] and /artists/[slug], which both render the ArtistScreen components.

Assuming these have different stacks in their Next.js pages, it's important that you set different names for inside of the react-navigation stacks.

For example, here these two stacks render the ArtistScreen, but the name must differ:

/artists/[slug] -> ArtistsStack -> <Screen name="artist" component={ArtistScreen} />
/my-artists/[slug] -> MyArtistsStack -> <Screen name="myArtist" component={ArtistScreen} />

You have to give a different name to the screen so that it can be uniquely identified within its stack relative to the root navigator.

If you don't do this, you get weird race conditions with back buttons on Web.

Leaving this here to document later.

On native, if you have a stack singleton, you can just do this:

       <NativeStack.Screen
          component={ArtistScreen}
          name="artist"
          getId={({ params }) => params?.slug}
        />
        <NativeStack.Screen
          component={ArtistScreen}
          name="myArtist"
          getId={({ params }) => params?.slug}
        />

Back button `pop` logic race condition

There is a very specific case that breaks the pop logic on web used for our custom BackButton behavior on the stack.

If you're on a screen, and hit back, it typically works. However, if the screen you're going back to satisfies the following condition, it breaks:

The screen you're going back to satisfies the linking path ''. That is, if you're going to myurl.com/, then this screen handles that route.

Issue

You can never click the back button and end up at the / route.

Example

Take this linking config:

 const linking = useLinkingConfig({
    prefixes: [Linking.makeUrl('/')], 
    config: {
      screens: { 
        artistsTab: {
          path: '',
          initialRouteName: 'artists',
          screens: {
            artist: 'artists/:slug',
          },
        },
      },
    },
  })

Explanation

In this case, we have 2 routes in play:

  • / routes to the artists screen name (ArtistsListScreen component)
  • /artists/:slug routes to the artist screen name (ArtistDetailScreen component)

Expected behavior

If you're in the artistsTab, and an artist screen is open (artists/djkhaled), clicking back should go to /, opening the artists screen.

Actual behavior

Going "back" from our custom BackButton component while on artists/djkhaled instead sends you back to /artists. This is entirely incorrect. It seems like it's doing this:

  • If the path to go back to matches "", then instead it takes the screen name of that route (in this case artists) and uses that in the URL.
    • This is entirely undesired.

More bad behavior

Similarly, when clicking back to a screen that had a parameter (artists/djkhaled), I have also had it go back to artists?slug=djkhaled), which was breaking the app, since my next.js page at pages/artists didn't have access to the artist detail screen.

Workaround

A workaround I don't love is this: Add a getPathFromState to your linking config, which transforms your initialRouteName bug and re-routes it to the home screen.

import { getPathFromState } from '@react-navigation/native'

const rootScreenName = 'artists'

 const linking = useLinkingConfig({
    prefixes: [Linking.makeUrl('/')], 
    getPathFromState(state, options) {
      const path = getPathFromState<ReactNavigation.RootParamList>(
        state,
        options
      )

      if (path == '/' + rootScreenName) {
        return '/'
      }

      if (path == '/' + rootScreenName + '?') {
        return '/' // TODO not sure what to do when this happens
      }
      return path
    },
    config: {
      screens: { 
        artistsTab: {
          path: '',
          initialRouteName: rootScreenName,
          screens: {
            artist: 'artists/:slug',
          },
        },
      },
    },
  })

Reproduction

I only have this in my app right now, so I would need to build a repro here still.

Shallow routing example

I have a cool example of shallow routing. It works great with a react navigation stack.

Say you have a stack with these screens:

  • artists โ†’ /artists
  • artist โ†’ /artists/:slug

When you're visiting either Next.js page, you're rendering the same stack.

The code looks like this:

// pages/artists/[slug] & pages/artists use the same component here

export default function ArtistPage() {
  return (
    <NativeStack.Navigator screenOptions={screenOptions}>
      <NativeStack.Screen
        name="artist"
        component={ArtistScreen}
        getId={({ params }) => params?.slug}
      />
      <NativeStack.Screen
        name="artists"
        component={ArtistsScreen}
      />
    </NativeStack.Navigator>
  )
}

A typical way to route from /artists โ†’ artists/:slug would be to do something like this:

router.push('/artists/drake')

However, this misses out on amazing Next.js feature: shallow routing.

Since every Next.js page is a React Navigation stack in this paradigm, we can take advantage of Next.js shallow routing out of the box. In fact, this is better than normal Next.js routing. It's amazing.

Dynamic example

Say were on the artists page at the URL /artists.

First, static code

To open an artist with shallow routing, we can do this:

router.push('/artists?slug=drake', '/artists/drake', { shallow: true })

And there we have it! That's literally all we have to do. Now, React Navigation will navigate on the client-side only, using the asPath set by /artists/drake.

Next, a dynamic example

Okay, but can we do better? Writing the href argument as /artists?slug=drake is a bit annoying. For example, what if our component doesn't know which screen it's navigating from?

Rather than hard code the first path, we can dynamically generate the href:

import Router from 'next/router'

// ...

const openArtist = () => {
  const as = '/artists/drake'

  let href = Router.router && {
    pathname: Router.pathname,
    query: { ...Router.query, slug: 'drake' }
  }

  href = href || as

  router.push(href, as, { shallow: true })
}

Okay, so what happened here?

Well, first we make sure that Router exists. If it doesn't, that means we're on native โ€“ in which case, we don't care about shallow routing, so we fall back to the actual URL.

Next, if Router exists, we just need to tell Next.js that we want to stay on the same URL we're already on, so we set the href.pathname = Router.pathname.

Finally, we set the query equal to the current query + any new query parameters we want our screen(s) to access { ...Router.query, slug: 'drake' }.

And there we have it. We've now navigated from the artists screen to artist, cross-platform, using shallow routing. If you go back, your scroll position is preserved, components aren't unmounted, giving users a great UX. In fact, I think this navigation pattern is better than typical Next router, since we can use it on like every page!

Looking forward

There are plans to create documentation from issues like this one, but I'm writing this here so that people along the way can get a sense of different patterns we're working on.

Expo publish not working properly

Hey guys!

Awesome project here.

I was playing around with it to check its functionality and where it may lead to, and possibilities are endless. Thanks a lot for sharing your knowledge and this great monorepo configuration.

I was able to deploy the nextjs app to AWS Amplify (just a bit of struggles because of AWS documentation was not super clear) but at the end work perfectly. That side of my CI/CD is going great.

The other side that is the expo publish flow for the native app, is not going so great. The publish completes successfully in the CLI but when trying to open in the Expo Go app, using the QR code, it hangs with a black or white screen. Tried several iPhones and the result is always the same. Rarely enough, the app works perfectly in development, even when putting the production mode on.

I tried to log errors to Sentry or something suspecting a crash might be happening, but with no success. I think it's related to something (maybe js) not loading properly, but my current knowledge is not letting me find the root cause.


To reproduce you can clone the repo, change the owner in the app.config.js to be able to publish to your own expo account and then:

yarn install
cd packages/expo
yarn publish:production

You'll get a successful output from Expo CLI as follows:

Bundle                              Size
โ”Œ index.ios.js (Hermes)           825 kB
โ”œ index.android.js (Hermes)       825 kB
โ”œ index.ios.js.map (Hermes)      3.45 MB
โ”” index.android.js.map (Hermes)  3.45 MB

๐Ÿ’ก JavaScript bundle sizes affect startup time. Learn more: https://expo.fyi/javascript-bundle-sizes

Analyzing assets
Saving assets
No assets changed, skipped.

Processing asset bundle patterns:
- /home/mora260/Projects/Learning/Mono/expo-next-monorepo-example-main/packages/expo/**/*

Uploading JavaScript bundles
Publish complete

๐Ÿ“  Manifest: https://exp.host/@amoraz/example/index.exp?release-channel=production&sdkVersion=43.0.0 Learn more: https://expo.fyi/manifest-url
โš™๏ธ   Project page: https://expo.dev/@amoraz/example?release-channel=production Learn more: https://expo.fyi/project-page

Done in 13.48s.

But if you go to that link and try to open it with the Expo Go iOS App, it will fail to start and show the Hello World.

Can you guys point me in the right direction on how to troubleshoot this issue?

Thanks a lot for any help!

example of path alias in the project?

Hi,

I was wondering if there's any example of using path aliases in the project?

I have been using path aliases in my standalone expo project. It was working fine and I just had to configure tsconfig.json and babel.config.js in order to make them work. However, I am not sure how we can use path aliases in such a project structure?

VSCode Intellisense

Hello! First, thank you for all of the work on this repo.

I was wondering if you have intellisense working for VSCode? When writing code in the App package intellisense works fine for other code written in the same package (ex: importing a customized button), but it doesn't work for any of the packages installed in the Expo package (react native, dripsy, etc.). If I install the package in the App package (understood that I should not do this) then everything works as expected, but I'm hoping there's an easy fix that I'm missing.

Thanks!

Problems runnning expo

So far I managed to run on NextJS, it's running smooth. I having problems running the expo part. (I'm not using expo-dev-client for now, just want to make it work first)

  1. The console.log is not working, does not give me any messages
  2. The fast refresh is not working, already checked the metro config, it seems to be right

next-images TypeError: unsupported file type: undefined

Hi,

I have installed everything correctly but still, I am facing this issue.

next-images TypeError: unsupported file type: undefined

Here's my next.config.js

const { withExpo } = require('@expo/next-adapter')
const withPlugins = require('next-compose-plugins')
const withFonts = require('next-fonts')
const withImages = require('next-images')

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true'
})
const withTM = require('next-transpile-modules')([
  'app',
  '@gorhom/bottom-sheet',
  'react-doorman',
  'react-native-doorman',
  '@gorhom/portal',
  'dripsy',
  '@dripsy/core'
])

const nextConfig = {}

module.exports = withPlugins(
  [
    withTM,
    withFonts,
    withImages,
    withBundleAnalyzer,
    [withExpo, { projectRoot: __dirname + '/../..' }]
  ],
  nextConfig
)

Thinking through `parse`-ing query parameters

One thing that's a bit confusing: if I do push({ pathname: '/artists/[slug]', query: { offer: 100, slug: 'djkhaled' }), it creates /artists/djkhaled?offer=100.

In that case, offer is "100", which is a string.

Using the parse function on useParam, we can turn this into a number:

useParam('offer', { parse: Number, initial: 0 })

However, useParam currently only runs the parse function on web. The reason being, on web, we know query params will always start out as strings, whereas on Native, they might be sent as actual primitive values, since this is possible for people to do with navigate('artist', { offer: 100 }).

In order to achieve the same parse-ing on both native and web, you have to add the parse option to your linking config, in addition to your useParam hook.

In reality, this should be set only once: in your linking config. But there are a few issues with that:

  • useParam is set up to expect you to parse within the hook, not from the linking config, and the types resemble that. It would require a refactor of this hook
  • If we want to define our query parameter parse only in the linking config (which would be ideal), then I need to figure out how React Navigation does this under the hood, and copy the same logic into useParam. This is probably doable, just a bit annoying.

On Web, it's harder to restrict users from giving you a messed up URL. A big reason that useParam has the parse function is to avoid people giving you bad states: offer=hello when offer should be a number.

On Native, this isn't as likely to happen, since people can't type a URL (unless they're deep linking, I guess, but that's a really rare case).

The ideal API: set parse and stringify in your linking config, and useParam just knows what do to on Web.

In fact...it's possible we could just use the react-navigation params on Web too. Maybe that would simplify all of this, rather than reading from nextRouter.query.

Support for Expo 44

I tried doing expo upgrade and ran into some issues with getting the app to load. Can we update this example to support the new expo?

Need to import `react`

I'm not totally sure why this is the case, but if you don't import React from 'react' in a JSX file, I'm seeing this error, even though we're on react 17.

Screen Shot 2021-10-24 at 12 19 31 PM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.