Last active
March 31, 2021 20:18
-
-
Save bretmorris/eee518f96229cb3bf6f1910efa14bd84 to your computer and use it in GitHub Desktop.
using use-query to get calendar events by search query and updating URL query params
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from 'react' | |
import { useQuery } from 'lib/use-query' | |
const CalendarListing = () => { | |
const [loading, setLoading] = useState(true) | |
const [queryParams, setQueryParams] = useState({}) | |
const [events, setEvents] = useState([]) | |
const getEvents = async () => { | |
const urlParams = new URLSearchParams(window.location.search) | |
const params = { | |
search: urlParams.get('search'), | |
} | |
setQueryParams(params) | |
setLoading(true) | |
const data = await fetch(`/api/calendar?${serialize(params)}`) | |
setEvents(data) | |
setLoading(false) | |
} | |
const { updateUrl, serialize } = useQuery(getEvents) | |
const search = (e) => { | |
e.preventDefault() | |
const { value } = document.getElementById('events-search') | |
changeParam('search', value) | |
} | |
const changeParam = (key, value) => { | |
const newQueryParams = { ...queryParams } | |
newQueryParams[key] = value | |
setQueryParams(newQueryParams) | |
updateUrl('/calendar', newQueryParams) | |
} | |
return ( | |
<> | |
<form onSubmit={search}> | |
<input | |
id="events-search" | |
placeholder="Search events" | |
defaultValue={queryParams.search} | |
/> | |
</form> | |
{!loading && | |
events && | |
events.length > 0 && | |
events.map((event, i) => ( | |
<div key={i}> | |
<div>Title: {event.title}</div> | |
<div>Description: {event.description}</div> | |
<div>Start: {event.start}</div> | |
<div>End: {event.end}</div> | |
</div> | |
))} | |
{!events || (events.length === 0 && !loading && <div>No events</div>)} | |
{loading && <div>loading...</div>} | |
</> | |
) | |
} | |
export default CalendarListing |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect } from 'react' | |
// cb: function to be called on component load and after URL changed | |
export const useQuery = (cb) => { | |
let event | |
useEffect(() => { | |
cb() | |
window.addEventListener('replaceState', cb) | |
return () => { | |
window.removeEventListener('replaceState', cb) | |
} | |
}, []) | |
// converts object into query param string | |
const serialize = (obj) => { | |
event = new Event('replaceState') | |
var str = [] | |
for (var key in obj) { | |
// eslint-disable-next-line no-prototype-builtins | |
if (obj.hasOwnProperty(key)) { | |
if (obj[key] && obj[key] !== 'undefined') { | |
str.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])) | |
} | |
} | |
} | |
return str.join('&') | |
} | |
// updates the query params of the url | |
const updateUrl = (path, params) => { | |
const queryString = serialize(params) | |
window.history.replaceState( | |
{ path: `${path}?${queryString}` }, | |
'', | |
`${path}?${queryString}` | |
) | |
// custom event to handle replaceState | |
window.dispatchEvent(event) | |
} | |
return { | |
updateUrl, | |
serialize, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment