# withEffects

Used to enhance a plain component, wrapping it in a WithEffects component which handles side-effects internally. It is a curried higher-order component.

## Packages

`withEffects` is provided by our React, Inferno or Preact packages - `refract-*`, `refract-inferno-*`, `refract-preact-*`.

## Signature

```javascript
withEffects = (
    aperture,
    config: { handler?, errorHandler?, Context?, mergeProps?, decorateProps? }
) => BaseComponent => {
    return WrappedComponent
}
```

## 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, initialProps, initialContext?) => { return effectStream }`.

   * The `component` is an object which lets you observe your React, Inferno or Preact component: see [Observing React](https://refract.js.org/usage/observing-react)
   * The `initialProps` are all props passed into the `WrappedComponent`.
   * The `initialContext` is the initial context value of the provided `Context` (see above, React >= 16.6.0 only)
   * 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. a `config` object optionally containing the following:
   1. `handler` *(function)*: an *optional* function which causes side-effects in response to `effect` values.

      Signature: `(initialProps, initialContext?) => (effect) => { /* handle effect here */ }`

      * The `initialProps` are all props passed into the `WrappedComponent`.
      * The `initialContext` is the initial context value of the provided `Context` (see below, React >= 16.6.0 only)
      * The `effect` is each value emitted by your `aperture`.
      * Within the body of the function, you cause any side-effect you wish.
   2. `errorHandler` *(function)*: an *optional* function for catching any unexpected errors thrown within your `aperture`. Typically used for logging errors.

      Signature: `(initialProps, initialContext?) => (error) => { /* handle error here */ }`

      * The `initialProps` are all props passed into the `WrappedComponent`.
      * The `initialContext` is the initial context value of the provided `Context` (see below, React >= 16.6.0 only)
      * The `error` is each value emitted by your `aperture`.
      * Within the body of the function, you cause any side-effect you wish.
   3. `Context` *(ReactContext)*: a React Context object. Its initial value will be passed to `handler`, `errorHandler` and `aperture` (React 16.6.0 and above only).
   4. `mergeProps`: whether or not props passed with `toProps` or `asProps` should be merged together.
   5. `decorateProps`: whether or not props which are functions should be decorated, so their arguments can be observed (default to `true`).
3. `BaseComponent` *(React component)*: any react component.

## Returns

`WrappedComponent` *(React component)*: a new component which contains your side-effect logic, and which will render your component as per usual.

## Example

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

const BaseComponent = ({ username, onChange }) => (
    <input value={username} onChange={onChange} />
)

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

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

const WrappedComponent = withEffects(aperture, { handler })(BaseComponent)
```

## Tips

* Take a look at our recipe for [dependency injection](https://refract.js.org/recipes/dependency-injection) into your Refract components.
* `withEffects` is curried so that you can re-use a bound `handler` (and `errorHandler`) with multiple different `apertures`.


---

# 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/witheffects.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.
