# useRefract

Used to create a custom hook.

## Packages

`useRefract` is provided by our React packages - `refract-*`. It is only available for versions of React supporting hooks (React 16.7.0-alpha.0 and above).

## Signature

```javascript
const useRefract = useRefract(aperture, data, {
    handler,
    errorHandler
})
```

## Arguments

1. `aperture` *(function)*: a function which observes data sources within your app, passes this data through any necessary logic flows, and outputs a stream of `effect` values in response.

   Signature: `(component, initialData) => { return effectStream }`.

   * The `initialData` passed to the hook (second argument).
   * The `component` is an object which lets you observe: see [Observing React](https://refract.js.org/usage/observing-react). The `observe` method allows you to observe `data` passed to your hook.
   * Within the body of the function, you observe the event source you choose, pipe the events through your stream library of choice, and return a single stream of effects.
2. `data` *(object)*: an object of data (state, props, context) passed to your hook.
3. `handler` *(function)*: a *optional* function which causes side-effects in response to `effect` values.

   Signature: `(initialData) => (effect) => { /* handle effect here */ }`

   * The `initialData` passed to the hook (second argument).
   * The `effect` is each value emitted by your `aperture`.
   * Within the body of the function, you cause any side-effect you wish.
4. `errorHandler` *(function)*: an *optional* function for catching any unexpected errors thrown within your `aperture`. Typically used for logging errors.

   Signature: `(initialData) => (error) => { /* handle error here */ }`

   * The `initialData` passed to the hook (second argument).
   * The `error` is each value emitted by your `aperture`.
   * Within the body of the function, you cause any side-effect you wish.

## Returns

`componentData` *(any)*: Refract hooks have a special built-in effect to push data to your component. Effects emitted by your aperture and wrapped with `toRender` will be returned by your hook.

```javascript
import { toRender } from 'refract-rxjs'
```

## Example

```javascript
import { useRefract } from 'refract-rxjs'

const handler = initialData => effect => {
    switch (effect.type) {
        case 'localstorage':
            localStorage.setItem(effect.name, effect.value)
            return
    }
}

const aperture = (component, initialData) => {
    return component.observe('username').pipe(
        debounceTime(2000),
        map(username => ({
            type: 'localstorage',
            name: 'username',
            value: username
        }))
    )
}

const BaseComponent = () => {
    const [ username, setUsername ] = useState()

    useRefract(aperture, { username }, { handler })

    return <input value={username} onChange={evt => setUsername(evt.target.value)} />
)
```

## Tips

Take a look at our recipe for [dependency injection](https://refract.js.org/recipes/dependency-injection) into your Refract components.
