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

Commit

Permalink
feat(infinite-hits): add example
Browse files Browse the repository at this point in the history
  • Loading branch information
eunjae-lee committed Apr 30, 2020
1 parent b7b8a24 commit 9f13f91
Show file tree
Hide file tree
Showing 9 changed files with 5,261 additions and 243 deletions.
26 changes: 26 additions & 0 deletions examples/infinite-hits-cache/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
This example shows how to synchronize your instantsearch url if you are using react-router.

## Clone the example

```
curl https://codeload.github.com/algolia/react-instantsearch/tar.gz/master | tar -xz --strip=2 react-instantsearch-master/examples/react-router
```

## Start the example

```sh
yarn install --no-lockfile
yarn start
```

Read more about react-instantsearch [in our documentation](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/react/).

## Use the development version (Using Yarn Workspace)

At the root of `react-instantsearch` package,

```sh
yarn install
yarn build
yarn workspace example-infinite-hits-cache start
```
33 changes: 33 additions & 0 deletions examples/infinite-hits-cache/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "example-infinite-hits-cache",
"version": "1.0.0",
"private": true,
"license": "MIT",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "CI=true react-scripts test"
},
"devDependencies": {
"history": "4.10.1",
"react-scripts": "3.1.2",
"react-test-renderer": "16.8.6"
},
"dependencies": {
"algoliasearch": "4.0.0-beta.15",
"instantsearch.css": "7.3.1",
"lodash": "4.17.15",
"prop-types": "15.6.0",
"qs": "6.8.0",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-instantsearch-dom": "6.4.0",
"react-router-dom": "5.0.1"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
11 changes: 11 additions & 0 deletions examples/infinite-hits-cache/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>react-router feat react-instantsearch</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
142 changes: 142 additions & 0 deletions examples/infinite-hits-cache/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import qs from 'qs';
import {
InstantSearch,
HierarchicalMenu,
Menu,
Pagination,
PoweredBy,
RatingMenu,
RefinementList,
SearchBox,
ClearRefinements,
Highlight,
InfiniteHits,
getInfiniteHitsSessionStorageCache,
} from 'react-instantsearch-dom';
import algoliasearch from 'algoliasearch/lite';

const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);

const updateAfter = 700;

const createURL = state => `?${qs.stringify(state)}`;

const searchStateToUrl = (props, searchState) =>
searchState ? `${props.location.pathname}${createURL(searchState)}` : '';
const urlToSearchState = location => qs.parse(location.search.slice(1));

function Product({ hit }) {
return (
<div>
<span>#{hit.__position}. </span>
<Highlight attribute="name" hit={hit} />
<p>
<a href="https://google.com">Details</a>
</p>
</div>
);
}
Product.propTypes = {
hit: PropTypes.object.isRequired,
};

class App extends Component {
state = {
searchState: urlToSearchState(this.props.location),
};

componentDidUpdate(prevProps) {
if (prevProps.location !== this.props.location) {
this.setState({ searchState: urlToSearchState(this.props.location) });
}
}

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

this.debouncedSetState = setTimeout(() => {
this.props.history.push(
searchStateToUrl(this.props, searchState),
searchState
);
}, updateAfter);

this.setState({ searchState });
};

render() {
return (
<InstantSearch
searchClient={searchClient}
indexName="instant_search"
searchState={this.state.searchState}
onSearchStateChange={this.onSearchStateChange}
createURL={createURL}
>
<div>
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 10,
}}
>
<SearchBox />
<PoweredBy />
</div>

<div style={{ display: 'flex' }}>
<div style={{ padding: '0px 20px' }}>
<p>Hierarchical Menu</p>
<HierarchicalMenu
id="categories"
attributes={[
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
'hierarchicalCategories.lvl2',
]}
/>
<p>Menu</p>
<Menu attribute="type" />
<p>Refinement List</p>
<RefinementList attribute="brand" />
<p>Range Ratings</p>
<RatingMenu attribute="rating" max={6} />
</div>

<div style={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
<div style={{ display: 'flex', justifyContent: 'space-around' }}>
<ClearRefinements />
</div>
<div>
<InfiniteHits
hitComponent={Product}
cache={getInfiniteHitsSessionStorageCache()}
/>
</div>
<div style={{ alignSelf: 'center' }}>
<Pagination showLast={true} />
</div>
</div>
</div>
</div>
</InstantSearch>
);
}
}

App.propTypes = {
history: PropTypes.shape({
push: PropTypes.func.isRequired,
}),
location: PropTypes.object.isRequired,
};

export default App;
15 changes: 15 additions & 0 deletions examples/infinite-hits-cache/src/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import renderer from 'react-test-renderer';
import App from './App';
import { createMemoryHistory } from 'history';

const history = createMemoryHistory('/');
const { location } = history;

describe('react-router recipe', () => {
it('App renders without crashing', () => {
const component = renderer.create(<App location={location} />);

expect(component.toJSON()).toMatchSnapshot();
});
});
Loading

0 comments on commit 9f13f91

Please sign in to comment.