Skip to content
This repository was archived by the owner on Dec 30, 2022. It is now read-only.

chore(examples): update next example to Next 12 #3438

Merged
merged 6 commits into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions examples/hooks-next/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Head from 'next/head';
import { GetServerSideProps } from 'next';
import algoliasearch from 'algoliasearch/lite';
import { Hit as AlgoliaHit } from 'instantsearch.js';
import {
Expand Down Expand Up @@ -82,15 +83,16 @@ function FallbackComponent({ attribute }: { attribute: string }) {
);
}

export async function getServerSideProps({ req }) {
const protocol = req.headers.referer?.split('://')[0] || 'https';
const url = `${protocol}://${req.headers.host}${req.url}`;
const serverState = await getServerState(<HomePage url={url} />);
export const getServerSideProps: GetServerSideProps<HomePageProps> =
async function getServerSideProps({ req }) {
const protocol = req.headers.referer?.split('://')[0] || 'https';
const url = `${protocol}://${req.headers.host}${req.url}`;
const serverState = await getServerState(<HomePage url={url} />);

return {
props: {
serverState,
url,
},
return {
props: {
serverState,
url,
},
};
};
}
26 changes: 0 additions & 26 deletions examples/next/.babelrc

This file was deleted.

81 changes: 28 additions & 53 deletions examples/next/components/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
RefinementList,
SearchBox,
Expand Down Expand Up @@ -33,56 +32,32 @@ const HitComponent = ({ hit }) => (
</div>
);

HitComponent.propTypes = {
hit: PropTypes.object,
};

export default class extends React.Component {
static propTypes = {
searchState: PropTypes.object,
resultsState: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
onSearchStateChange: PropTypes.func,
createURL: PropTypes.func,
indexName: PropTypes.string,
searchClient: PropTypes.object,
};

render() {
return (
<InstantSearch
searchClient={this.props.searchClient}
resultsState={this.props.resultsState}
onSearchStateChange={this.props.onSearchStateChange}
searchState={this.props.searchState}
createURL={this.props.createURL}
indexName={this.props.indexName}
onSearchParameters={this.props.onSearchParameters}
{...this.props}
>
<Configure hitsPerPage={12} />
<header>
<h1>React InstantSearch + Next.Js</h1>
<SearchBox />
</header>
<main>
<div className="menu">
<RefinementList attribute="categories" />
</div>
<div className="results">
<Hits hitComponent={HitComponent} />
</div>
</main>
<footer>
<Pagination />
<div>
See{' '}
<a href="https://github.com/algolia/react-instantsearch/tree/master/examples/next">
source code
</a>{' '}
on github
</div>
</footer>
</InstantSearch>
);
}
export function App(props) {
return (
<InstantSearch {...props}>
<Configure hitsPerPage={12} />
<header>
<h1>React InstantSearch + Next.js</h1>
<SearchBox />
</header>
<main>
<div className="menu">
<RefinementList attribute="categories" />
</div>
<div className="results">
<Hits hitComponent={HitComponent} />
</div>
</main>
<footer>
<Pagination />
<div>
See{' '}
<a href="https://github.com/algolia/react-instantsearch/tree/master/examples/next">
source code
</a>{' '}
on GitHub
</div>
</footer>
</InstantSearch>
);
}
10 changes: 0 additions & 10 deletions examples/next/components/head.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import NextHead from 'next/head';
import { string } from 'prop-types';
import React from 'react';

const defaultDescription = '';
Expand Down Expand Up @@ -34,12 +33,3 @@ export const Head = (props) => (
<link rel="stylesheet" href="instantsearch.css" />
</NextHead>
);

Head.propTypes = {
title: string,
description: string,
url: string,
ogImage: string,
};

export default Head;
2 changes: 1 addition & 1 deletion examples/next/components/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './head';
export { default as App } from './app';
export * from './app';
17 changes: 0 additions & 17 deletions examples/next/next.config.js

This file was deleted.

20 changes: 12 additions & 8 deletions examples/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@
"build": "next build",
"start": "next start"
},
"devDependencies": {
"babel-core": "7.0.0-bridge.0",
"babel-jest": "23.6.0",
"css-loader": "3.2.0",
"style-loader": "1.0.0"
"jest": {
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": [
"babel-jest",
{
"presets": [
"next/babel"
]
}
]
}
},
"dependencies": {
"algoliasearch": "4.11.0",
"next": "9.1.1",
"prop-types": "15.6.2",
"next": "12.1.5",
"qs": "6.8.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-fast-compare": "3.0.1",
"react-instantsearch-dom": "6.23.3"
}
}
110 changes: 46 additions & 64 deletions examples/next/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import isEqual from 'react-fast-compare';
import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'next/router';
import { useRouter } from 'next/router';
import qs from 'qs';
import algoliasearch from 'algoliasearch/lite';
import { findResultsState } from 'react-instantsearch-dom/server';
Expand All @@ -27,70 +25,54 @@ const DEFAULT_PROPS = {
indexName: 'instant_search',
};

class Page extends React.Component {
static propTypes = {
router: PropTypes.object.isRequired,
resultsState: PropTypes.object,
searchState: PropTypes.object,
};

state = {
searchState: this.props.searchState,
lastRouter: this.props.router,
};

static async getInitialProps({ asPath }) {
const searchState = pathToSearchState(asPath);
const resultsState = await findResultsState(App, {
...DEFAULT_PROPS,
searchState,
});

return {
resultsState,
searchState,
};
}
export default function Page(props) {
const [searchState, setSearchState] = React.useState(props.searchState);
const router = useRouter();
const debouncedSetState = React.useRef();

static getDerivedStateFromProps(props, state) {
if (!isEqual(state.lastRouter, props.router)) {
return {
searchState: pathToSearchState(props.router.asPath),
lastRouter: props.router,
};
React.useEffect(() => {
if (router) {
router.beforePopState(({ url }) => {
setSearchState(pathToSearchState(url));
});
}
}, [router]);

return (
<div>
<Head title="Home" />
<App
{...DEFAULT_PROPS}
searchState={searchState}
resultsState={props.resultsState}
onSearchStateChange={(nextSearchState) => {
clearTimeout(debouncedSetState.current);

debouncedSetState.current = setTimeout(() => {
const href = searchStateToURL(nextSearchState);

router.push(href, href, { shallow: true });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to overwrite the router history, not to append (see preview).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you screen record?

Untitled.mov

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to happen when you open the CodeSandbox app in a tab. It might be another CodeSandbox bug.

}, updateAfter);

setSearchState(nextSearchState);
}}
createURL={createURL}
/>
</div>
);
}

return null;
}

onSearchStateChange = (searchState) => {
clearTimeout(this.debouncedSetState);

this.debouncedSetState = setTimeout(() => {
const href = searchStateToURL(searchState);

this.props.router.push(href, href, {
shallow: true,
});
}, updateAfter);
export async function getServerSideProps({ resolvedUrl }) {
const searchState = pathToSearchState(resolvedUrl);
const resultsState = await findResultsState(App, {
...DEFAULT_PROPS,
searchState,
});

this.setState({ searchState });
return {
props: {
resultsState: JSON.parse(JSON.stringify(resultsState)),
searchState,
},
};

render() {
return (
<div>
<Head title="Home" />
<App
{...DEFAULT_PROPS}
searchState={this.state.searchState}
resultsState={this.props.resultsState}
onSearchStateChange={this.onSearchStateChange}
createURL={createURL}
/>
</div>
);
}
}

export default withRouter(Page);
7 changes: 7 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
declare const __DEV__: boolean;

declare namespace NodeJS {
// override the type set by Next (in examples), which sets NODE_ENV to readonly globally
interface ProcessEnv {
NODE_ENV: 'development' | 'production' | 'test';
}
}
Loading