Skip to content

Commit

Permalink
docs: first version of README
Browse files Browse the repository at this point in the history
  • Loading branch information
asmyshlyaev177 committed Jun 30, 2024
1 parent 619c658 commit 26cdb75
Showing 1 changed file with 177 additions and 1 deletion.
178 changes: 177 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,177 @@
# usl-state
[![For hire](/hireBadge.svg)](https://www.linkedin.com/in/asmyshlyaev177/)

# urlstate

![logo](/assets/logo.gif)

[![npm](https://img.shields.io/npm/v/urlstate.svg)](https://www.npmjs.com/package/urlstate)
![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/urlstate.svg)

When working with Next.js client components sometimes you need to pass values between them, using `useSearchParams` is a good solution, but this library can help you to serialize complex objects and will preserve types. It is more convinient and types-safe solution for state management.

## useUrlState hook

`useUrlState` is a custom React hook for Next.js applications that manages state in the URL query string. It allows you to store and retrieve state from the URL search parameters, providing a way to persist state across page reloads and share application state via URLs.


### Usage examples

#### Basic

```typescript
'use client'
import { useUrlState } from 'urlstate';

// State shape should be stored in a constant, don't pass an object directly
const countState = { count: 0 };

function MyComponent() {
const { state, updateState, updateUrl } = useUrlState(countState);

// won't let you to accidently mutate state directly, requires TS
// state.count = 2 // <- error

return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => updateUrl({ count: state.count + 1 })}>
Increment (Update URL)
</button>

<button onClick={() => updateState({ count: state.count + 1 })}>
Increment (Local Only)
</button>
<button onClick={() => updateUrl(state)}>
Sync changes to url
</button>
</div>
)
}
```

#### With complex state shape

```typescript
'use client'
import { useUrlState } from 'urlstate';

interface UserSettings {
theme: 'light' | 'dark';
fontSize: number;
notifications: boolean;
}

const defaultSettings: UserSettings {
theme: 'light',
fontSize: 16,
notifications: true,
}

function SettingsComponent() {
// `state` will infer from UserSettings type!
const { state, updateUrl } = useUrlState(defaultSettings);

const toggleTheme = () => {
updateUrl(current => ({
...current,
theme: current.theme === 'light' ? 'dark' : 'light',
}));
};

return (
<div>
<h2>User Settings</h2>
<p>Theme: {state.theme}</p>
<p>Font Size: {state.fontSize}px</p>
<button onClick={toggleTheme}>Toggle Theme</button>
{/* Other UI elements to update other settings */}
</div>
);
}
...

// Other component
function Component() {
const { state } = useUrlState(defaultSettings);

return (
<div>
<p>Notifications is {state.notifications ? 'On' : 'Off'}</p>
</div>
)
}
```

#### With arbitrary state shape (not recommended)

```typescript
'use client'
import { useUrlState } from 'urlstate';

const someObj = {};

function SettingsComponent() {
const { state, updateUrl, updateState } = useUrlState<object>(someObj);
}
```

## useUrlEncode hook

`useUrlEncode` is a custom React hook that provides utility functions for encoding and decoding state to and from URL search parameters. This hook doesn't depend on Nextjs, and will works with any React application.

Accepts optional defaultState argument.

```typescript
import { useUrlEncode } from 'urlstate';

const Component = () => {
const { parse, stringify } = useUrlEncode();

const str = stringify({ age: 36 }); // age=∓36
const obj = parse(str); // { age: 36 }

const currentParams = parse(window.location.search);
// OR
// const obj = parse(new URLSearchParams(window.location.search))

const updateSearch = () => {
const currentParams = new URLSearchParams(window.location.search);
const newState = { query: 'react hooks', page: 2 };
const updatedParamsString = stringify(newState, currentParams);
console.log(updatedParamsString);
// Output: existing params + query=react%20hooks&page=2
};
}
```

## `encode` and `decode` helpers

There low level helpers to stringify and parse query string params. Useful for other frameworks or pure JS.

```javascript
import { encode, decode } from 'urlstate';

const state = encode({ obj: [1, 2, 3] });

// to params
const params = new URLSearchParams();
Object.entries(state).forEach(([key, value]) => {
params.set(key, encode(value));
});

// from params
const obj = Object.fromEntries(
[...params.entries()].map(([key, value]) => [
key,
decode(value),
]),
)
```

## Gothas

1. Can pass only serializable values, `Function`, `BigInt` or `Symbol` won't work, probably things like `ArrayBuffer` neither. But won't throw an error if you do it accidently.
2. Developed and tested with recent `Next.js` and `Typescript` versions.


## [Changelog](https://github.com/asmyshlyaev177/urlstate/blob/main/CHANGELOG.md)

0 comments on commit 26cdb75

Please sign in to comment.