# 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](/usage/observing-react.md). 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](/recipes/dependency-injection.md) into your Refract components.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://refract.js.org/api/userefract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
