Skip to content

Instantly share code, notes, and snippets.

@swyxio
Last active July 26, 2022 10:43
Show Gist options
  • Save swyxio/efd9ee71669413bca6a895d87e30742f to your computer and use it in GitHub Desktop.
Save swyxio/efd9ee71669413bca6a895d87e30742f to your computer and use it in GitHub Desktop.
Sync your state to your query params for copy-pastable state-in-URLs. React Router, Gatsby, and Svelte versions
// note - this was my rough working prototype, but still left some artifacts in the query params.
// todo: also need to debounce the history pushes
// see comments for production Gatsby and Svelte versions which delete nondefault keys in the query params
import React from 'react'
import queryString from "query-string"
export const connectRouterState = defaultURLState => Component => props => {
const { history, location } = props
// note: do not nest objects in URL state
const urlState = { ...defaultURLState, ...queryString.parse(location.search) }
const setURLState = newState =>
history.push({ search: `?${queryString.stringify({ ...urlState, ...newState })}` })
return <Component
setURLState={setURLState}
urlState={urlState}
{...props}
/>
}
// usage example - assumes this connected component is provided `location` and `history` by react-router
class MyApp extends Component {
render() {
const { urlState, setURLState } = this.props
return (
<div>
<button onClick={() => setURLState({ newState: [1, 2] })}>{JSON.stringify(urlState)}</button>
</div>
)
}
}
export default connectRouterState({ defaultState: 1 })(MyApp)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment