> For the complete documentation index, see [llms.txt](https://soofty.gitbook.io/react-shared-state/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://soofty.gitbook.io/react-shared-state/documentation.md).

# Documentation

## Basic concepts

To understand how to use the library you should only understand 3 basic things

* State&#x20;
* Store
* Provider

### State

**State** is a just a dataset. For example a simple state that contains user name could be represented as

```javascript
{
    name: "Luke Skywalker"
}
```

### **Store**

**Store** is a JavaScript class that have a `state` **property and** `setState` method.

{% code title="minimal-store-example.js" %}

```jsx
import { SharedStore } from 'react-shared-state'

class MyStore extends SharedStore {}
```

{% endcode %}

`State` property is an empty object by default

```javascript
const store = new MyStore()
console.log(store.state) // {}
```

To update the `state` you should use `setState` method.

```javascript
store.setState({name: "Luke SkyWalker"})
console.log(store.state) // {name: "Luke SkyWalker"}
```

It works the same as react's [setState](https://reactjs.org/docs/react-component.html#setstate) method

{% hint style="danger" %}
Don't update state directly or your changes will be ignored
{% endhint %}

{% hint style="info" %}
Right now setState accepts only object to update the state. Using *updater* as a function doesn't supported
{% endhint %}

### Provider

**Provider** is a component that keeps your **store** and pass the **store** to your components.

To create provider call `createProvider`

{% code title="name-provider.js" %}

```jsx
const NameProvider = createProvider()
```

{% endcode %}

You add it to the root component of your application.

{% code title="app.js" %}

```jsx
import { NameProvider } from './simple-provider'

export function App() {
  return (
    // We fill default state with a name
    <NameProvider initialState={{ name: 'Luke SkyWalker' }}> 
      ...
    </NameProvider>
  )
}
```

{% endcode %}

After that you can use it in your components using `YourProvider.connect`

{% code title="hello.js" %}

```jsx
import { NameProvider } from './name-provider.js'

const HelloComponent = (props) => {
  <div>
    <h1> Hello, {props.name}</h1>
    <button onClick={() => props.store.setState({ name: 'Darth Vader' })}>Set Name</button>
  </div>
}

export const Hello = NameProvider.connect((store, ownProps) => ({
  store,
  name: store.state.name
}))(HelloComponent)
```

{% endcode %}

Connect is a High Ordered Component that accepts a `mapStoreToProps` callback with two arguments:

* `store` — a store instance being automatically created
* `ownProps` — props passed to the component

To update the state you can use `store.setState()`

To access the state use `store.state`

## Extending store

While you can use `setState` to change you **state** it's better to hide your logic with custom methods implementation

For example instead of setting name using `setState` it's better to add a custom method `setName`.

First of all let's create a **Store** class and pass it to `createProvider`.

{% code title="provider.js" %}

```jsx
import { createProvider, SharedStore } from 'react-shared-state''

class NameStore extends SharedStore {
    setName = (newName) => {
        this.setState({
            name: newName
        })
    }
}

const NameProvider = createProvider('name_provider', NameStore)
```

{% endcode %}

Now you can use it in your component in props

```jsx
import { NameProvider } from './name-provider.js'

const HelloComponent = (props) => {
  return <div>
    <h1> Hello, {props.name}</h1>
    <button onClick={() => props.setName({ name: 'Darth Vader' })}>Set Name</button>
  </div>
}

export const Hello = NameProvider.connect((store, ownProps) => ({
  setName: store.setName,
  name: store.state.name
}))(HelloComponent)
```

{% hint style="info" %}
Since we've used class properties definition `()=>` to declare the method we can pass it in `mapStoreToProps`.
{% endhint %}

{% hint style="danger" %}
Never pass `setState` method in `mapStoreToProps` because it's not declared as property in base state class and will fail to set state.
{% endhint %}

## Using State with API calls

Sometimes you have to get some data from the external source, for example API. Wonder where to add it? Just add it the store!

{% code title="provider.js" %}

```jsx
import { createProvider, SharedStore } from "react-shared-state";

class NameStore extends SharedStore {
  setName = newName => {
    this.setState({ name: newName });
  };
  fetchName = () => {
    this.setState({ loading: true });
    fetch("https://swapi.co/api/people/2/?format=json")
      .then(resp => resp.json())
      .then(data => {
        this.setState({ name: data.name });
        this.setState({ loading: false });
      });
  };
}

export const NameProvider = createProvider('', NameStore);
```

{% endcode %}

And use as a simple call

{% code title="hello.js" %}

```jsx
const HelloComponent = props => {
  if (props.loading) {
    return <h1>Loading...</h1>;
  }
  return (
    <div>
      <h1> Hello, {props.name}</h1>
      <button onClick={() => props.setName("Darth Vader")}>Set Name</button>
      <button onClick={() => props.fetchName()}>Fetch Name</button>
    </div>
  );
};

export const Hello = NameProvider.connect((store, ownProps) => ({
  fetchName: store.fetchName,
  setName: store.setName,
  name: store.state.name,
  loading: store.state.loading
}))(HelloComponent);
```

{% endcode %}

Also we've added a `loading` flag to indicate something is going one.

Working example available at <https://codesandbox.io/s/wy308n0k88>

## Logging

You can add logging for all stores

```javascript
import { ProviderComponent} from 'react-shared-state'

ProviderComponent.DEBUG = true
```

�or individually

```jsx
<SimpleProvider ... debug={true}>
   ...
</SimpleProvider>
```

![](/files/-LIapIE-ltOO46eYSNaM)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://soofty.gitbook.io/react-shared-state/documentation.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.
