Skip to content

Commit

Permalink
docs(readme): add usage section
Browse files Browse the repository at this point in the history
  • Loading branch information
smmoosavi committed Jan 7, 2022
1 parent bd3c7ba commit e9d0e25
Showing 1 changed file with 100 additions and 0 deletions.
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ connect react components with wire
- [Motivation](#motivation)
- [Install](#install)
- [Usage](#usage)
- [API](#api)
- [`useWire` hook](#usewire-hook)
- [`useWireValue` hook](#usewirevalue-hook)
- [`useWireState` hook](#usewirestate-hook)
Expand Down Expand Up @@ -52,6 +53,105 @@ Add [proxy-polyfill](https://github.com/GoogleChrome/proxy-polyfill) to support

## Usage

With pure react, you use `useState` to store state:

```tsx
function FancyInput(props) {
const [value, setValue] = useState('');

return <input value={value} onChange={(e) => setValue(e.target.value)} />;
}
```

```tsx
function FancyPage() {
return <FancyInput />;
}
```

But sometimes, you need to use the state outside of the component; for example, you want to use the state to filter a list, so you have to move the state to the parent component:

```diff
function FancyInput(props) {
- const [value, setValue] = useState('');
+ const { value, setValue } = props;

return <input value={value} onChange={(e) => setValue(e.target.value)} />;
}
```

```tsx
function FancyList(props) {
const [filter, setFilter] = useState('');
return (
<>
<FnacyInput value={filter} setValue={setFilter} />
<List items={props.items} filter={filter} />
</>
);
}
```

- you need to refactor all `FancyInput` usage, pass `value`, and `setValue` to make it work as expected
- the top-level component (`FancyList`) re-render each time the `filter` changes

Let see how react-wire help you:

```tsx
function FancyInput(props) {
const [value, setValue] = useWireState(null, '');

return <input value={value} onChange={(e) => setValue(e.target.value)} />;
}
```

Same as above, but use `useWireState` instead of `useState`, right now `FancyInput` is uncontrolled. Now, if you need to make it controllable, you should pass an up-link wire.

```diff
function FancyInput(props) {
- const [value, setValue] = useWireState(null, '');
+ const [value, setValue] = useWireState(props.value$, '');

return <input value={value} onChange={(e) => setValue(e.target.value)} />;
}
```

And create a wire with the `useWire` hook and pass it to components:

```tsx
function FancyList(props) {
const filter$ = useWire(null, '');
return (
<>
<FnacyInput value$={filter$} />
<List items={props.items} filter$={filter$} />
</>
);
}
```

With this new code:

- all `FancyInput` uncontrolled usage is working as expected without any change
- the Top-level component (`FancyList`) will not re-render each time the value changes
- only detailed components (`FancyInput`, `List`) will re-render each time the value changes
- `FancyInput` is now controllable and can be used as a controlled or uncontrolled component by passing a wire.
- `FancyList` can be controllable if you want:

```tsx
function FancyList(props) {
const filter$ = useWire(props.filter$, '');
/* ... */
}
```

react-wire have more advanced features:

- selectors to maintain calculated values
- fns to pass function calls over the wire

## API

### `useWire` hook

`useWire` hook creates and returns new wire. in the next renders, returns the same wire.
Expand Down

0 comments on commit e9d0e25

Please sign in to comment.