-
-
Save necolas/f9034091723f1b279be86c7429eb0c96 to your computer and use it in GitHub Desktop.
import NextLink from 'next/link'; | |
import React from 'react'; | |
import { Text } from 'react-native-web'; | |
// https://github.com/zeit/next.js#with-link | |
// Combines the Next.js <Link> with React Native's <Text> component. | |
// Enables use like this: | |
// | |
// <Link | |
// href={href} | |
// prefetch | |
// style={styles.enhance} | |
// > | |
// Link text | |
// </Link> | |
// | |
export default Link extends React.Component { | |
static propTypes = { | |
...NextLink.propTypes, | |
...Text.propTypes | |
} | |
blur() { | |
this._textRef.blur(); | |
} | |
focus() { | |
this._textRef.focus(); | |
} | |
setNativeProps(props) { | |
this._textRef.setNativeProps(props) | |
} | |
_setRef = (c) => { | |
this._textRef = c; | |
} | |
render() { | |
const { | |
as, | |
passHref, // ignore | |
scroll, | |
shallow, | |
replace, | |
...rest | |
} = this.props; | |
return ( | |
<NextLink | |
href={href} | |
passHref={true} | |
prefetch={prefetch} | |
replace={replace} | |
scroll={scroll} | |
shallow={shallow} | |
> | |
<Text | |
accessibilityRole='link' | |
ref={this._setRef} | |
{...rest} | |
/> | |
</NextLink> | |
) | |
} | |
} |
import React from 'react'; | |
import Router from 'next/router'; | |
import { Text } from 'react-native-web'; | |
// https://github.com/zeit/next.js#imperatively | |
export default Link extends React.Component { | |
static propTypes = Text.propTypes; | |
blur() { | |
this._textRef.blur(); | |
} | |
focus() { | |
this._textRef.focus(); | |
} | |
setNativeProps(props) { | |
this._textRef.setNativeProps(props) | |
} | |
_handlePress = () => { | |
Router.push(this.props.href); | |
} | |
_setRef = (c) => { | |
this._textRef = c; | |
} | |
render() { | |
return ( | |
<Text | |
accessibilityRole='link' | |
onPress={this._handlePress} | |
ref={this._setRef} | |
{...rest} | |
/> | |
) | |
} | |
} |
I guess you don't need Expo to use this code. React-native-web is a package you can install without Expo
Thanks for this codes. I'm already using nextjs web for other projects and looking at react-native-web to get the current twitter experience.
With NextJS navigation, do we skip react-native navigation completely? What is the adviseable way to handle navigation for react-native-web?
@daveteu It depends on what you want your end product to be. You can use map react-router/native
and react-router
to a platform file. This would make it really easy to manage routing for ios/android/web. It would look something like this:
// react-router.native.js
import {
Link as NativeLink,
MemoryRouter,
Redirect as NativeRedirect,
Route as NativeRoute,
Switch as NativeSwitch,
withRouter as nativeWithRouter,
useHistory as nativeUseHistory,
useLocation as nativeUseLocation,
useParams as nativeUseParams,
useRouteMatch as nativeUseRouteMatch,
} from 'react-router-native';
export const Router = MemoryRouter;
export const Route = NativeRoute;
export const Link = NativeLink;
export const Switch = NativeSwitch;
export const Redirect = NativeRedirect;
export const withRouter = nativeWithRouter;
export const useHistory = nativeUseHistory;
export const useLocation = nativeUseLocation;
export const useParams = nativeUseParams;
export const useRouteMatch = nativeUseRouteMatch;
and
//react-router.web.js
import {
Link as WebLink,
Redirect as WebRedirect,
Route as WebRoute,
Switch as WebSwitch,
withRouter as webWithRouter,
useHistory as webUseHistory,
useLocation as webUseLocation,
useParams as webUseParams,
useRouteMatch as webUseRouteMatch,
} from 'react-router-dom'; // Or use next router if you like
export const Router =
typeof document !== 'undefined'
? require('react-router-dom').BrowserRouter
: require('react-router-dom').StaticRouter;
export const Route = WebRoute;
export const Link = WebLink;
export const Switch = WebSwitch;
export const Redirect = WebRedirect;
export const withRouter = webWithRouter;
export const useHistory = webUseHistory;
export const useLocation = webUseLocation;
export const useParams = webUseParams;
export const useRouteMatch = webUseRouteMatch;
Then use it like so:
import { Redirect, Route, Router, Switch } from 'common/react-router';
<Router
initialEntries={Platform.OS !== 'web' && generatedEntries}
initialIndex={Platform.isWeb && generatedEntries.indexOf(entryPoint)}
>
<Switch>
<Route path="/some-path" render={({ match }) => <SomePage />)} />
<Route path="/some-other-path" render={({ match }) => <SomeOtherPage />)} />
</Switch>
</Router>
From what I remember this doesn't give you a stack navigator when you compile the native app though. If you did want that experience then you could have two entries points that also have the respective navigators. More maintenance but IMO better experience. This would then give you the option to use the next/link, next/router etc in the web entry point.
Hey Necolas
My team is trying to use react-native codebase for a webapp with Nextjs to handle performance and server side rendering. They want to do it without expo - trying to help them find a solution if you have any ideas or interest to provide guidance? Thanks! :)