# Share a State Manager Across Components

To share a state manager instance across components, all *consumer* components must be children of a parent *provider* component that creates or acquires a reference to the shared state manager. In consumer components, use the `fromContext` function to retrieve a reference to the shared state manager.

## State Manager Context

A state manager instance is available to the component that creates it, and to all descendant components. Only the outer, enclosing component needs to create the state manager instance. Descendant consumer components must import the state manager definition, but instead of creating a state manager, they retrieve a reference to an existing state manager instance from their component context.

Consumers retrieve the closest state manager instance of the requested type, starting with themselves, and working upwards in their component hierarchy.

## Shared State Manager Considerations

State manager instances are resolved when a component, whether provider or consumer, is connected to the DOM.

That is, the provider component:

- Must have a reference to the state manager instance in one of its properties when it's connected to the DOM.
- Must not change that reference after it's connected (the behavior is undefined if it does).

And the consumer component:

- Does not receive a reference to the state manager instance until it's connected to the DOM.
- Must not try to reference the state manager instance's value before the component is connected to the DOM. For example, in its constructor or any code that might be called from its constructor.

:::tip
Diving a little deeper, all of the state manager context "magic" happens when the component is connected to the DOM. In the diagram in [Lifecycle Hooks](/docs/platform/lwc/guide/create-lifecycle-hooks.md), for the provider component, resolving the state manager context happens in the "Parent inserted into DOM" box. For the consumer component, resolution happens in the "Child inserted into DOM" box.

This constraint means that the provider must set the state manager property during construction or initial property processing, and the consumer won't have its reference to the state manager until its `connectedCallback` runs.
:::

## Shared State Manager Example

This example is visually identical to the all-in-one example component from [Implement a State Manager](/docs/platform/lwc/guide/state-management-define-implementation.md), but each UI element is defined in a separate component. The state of the counter is maintained in the `smCounter` state manager, and shared across all components.

### smCounter State Manager API Module

:::tip
It's a best practice to define your state manager in a separate [API module component](/docs/platform/lwc/guide/js-share-code.md). That makes it easy to import the state manager into any component that uses it.
:::

The state manager component has no user interface, and no `.html` template file.

```sfdocs-code {"lang":"javascript", "title": "smCounter.js" }
import { defineState } from '@lwc/state';

const counterManager = defineState(
    ({ atom, computed, setAtom }, initialValue = 0) => {

        // Create reactive value
        const count = atom(initialValue);

        // Create computed (and reactive) value
        const doubleCount = computed([count], (countValue) => countValue * 2);

        // Create a function that increments the count value
        const increment = () => {
            setAtom(count, count.value + 1);
        };

        // Create a function that directly sets the count atom
        const setCount = (newValue) => {
            setAtom(count, Number(newValue));
        };

        // This defines the API shape of counterManager
        return {
            count,
            doubleCount,
            increment,
            setCount,
        };
    }
);
export default counterManager;
```

### multiCounter Parent Component

The `multiCounter` component creates an instance of a shared state manager in the JavaScript file, and composes together the child components that make up the user interface in its `.html` template file.

```sfdocs-code {"lang":"javascript", "title": "multiCounter.js" }
import { LightningElement } from 'lwc';
import counterManager from 'c/smCounter';

export default class MultiCounter extends LightningElement {
    counter = counterManager(100);
}
```

```sfdocs-code {"lang":"html", "title": "multiCounter.html" }
<template>
    <lightning-card title="Example: Multi-Counter">
        <c-counter-display></c-counter-display>
        <c-counter-increment></c-counter-increment>
        <c-counter-set></c-counter-set>
        <c-counter-debug-state></c-counter-debug-state>
    </lightning-card>
</template>
```

### Descendant Components

The user interface for viewing and interacting with the counter state manager is made up of four components, each of which retrieves the shared `smCounter` state manager using the `fromContext` function.

The `c-counter-display` component retrieves the shared counter and displays the `count` and `doubleCount` values.

```sfdocs-code {"lang":"javascript", "title": "counterDisplay.js" }
import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import counterManager from 'c/smCounter';

export default class CounterDisplay extends LightningElement {
    counter = fromContext(counterManager);
}
```

```sfdocs-code {"lang":"html", "title": "counterDisplay.html" }
<template>
    <section class="slds-p-around_small">
        <p>Count: {counter.value.count}</p>
        <p>Doubled: {counter.value.doubleCount}</p>
    </section>
</template>
```

The `c-counter-increment` component retrieves the shared counter and provides a button that calls the `increment()` action.

```sfdocs-code {"lang":"javascript", "title": "counterIncrement.js" }
import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import counterManager from 'c/smCounter';

export default class CounterIncrement extends LightningElement {
    counter = fromContext(counterManager);

    increment() {
        this.counter.value.increment();
    }

}
```

```sfdocs-code {"lang":"html", "title": "counterIncrement.html" }
<template>
    <section class="slds-p-around_small">
        <lightning-button label="Increment" onclick={increment}></lightning-button>
    </section>
</template>
```

The `c-counter-set` component retrieves the shared counter, takes a numeric input, and calls `setCount()` to set the value.

```sfdocs-code {"lang":"javascript", "title": "counterSet.js" }
import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import counterManager from 'c/smCounter';

export default class CounterSet extends LightningElement {
    counter = fromContext(counterManager);

    setCount() {
        this.counter.value.setCount(Number(this.refs.newValue.value));
    }

}
```

```sfdocs-code {"lang":"html", "title": "counterSet.html" }
<template>
    <section class="slds-p-around_small">
        <lightning-input type="text" label="Counter"
            value={counter.value.count} lwc:ref="newValue"></lightning-input>
        <lightning-button label="Set Counter" onclick={setCount}></lightning-button>
    </section>
</template>
```

The `c-counter-debug-state` component retrieves the shared counter and renders the entire state as formatted JSON for debugging.

```sfdocs-code {"lang":"javascript", "title": "counterDebugState.js" }
import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import counterManager from 'c/smCounter';

export default class CounterDebugState extends LightningElement {
    counter = fromContext(counterManager);
    get stateDump() {
        return JSON.stringify(this.counter.value, null, 2);
    }

}
```

```sfdocs-code {"lang":"html", "title": "counterDebugState.html" }
<template>
    <hr/>
    <section class="slds-p-around_small">
        <textarea rows="10" cols="40">{stateDump}</textarea>
    </section>
    <hr/>
</template>
```
