# Redux integration

Using [redux](https://redux.js.org/) is completely optional. However, for many it means easy integration or migration
with existing projects, or just a nice centralized state management abstraction.

**just Reactive Data Client**

```tsx title="index.tsx"
import {
  ExternalDataProvider,
  prepareStore,
  type Middleware,
} from '@data-client/react/redux';
import { getDefaultManagers, Controller } from '@data-client/react';
import { createRoot } from 'react-dom/client';
import App from './App';

const managers = getDefaultManagers();
// be sure to include your other reducers here
const otherReducers = {};
const extraMiddlewares: Middleware[] = [];
// for instance, state serialized from the server
const initialState = {};

const { store, selector, controller } = prepareStore(
  initialState,
  managers,
  Controller,
  otherReducers,
  extraMiddlewares,
);

createRoot(document.body).render(
  <ExternalDataProvider
    store={store}
    selector={selector}
    controller={controller}
  >
    <App />
  </ExternalDataProvider>,
);
```

**with React-Redux**

```tsx title="index.tsx"
import {
  ExternalDataProvider,
  prepareStore,
  type Middleware,
} from '@data-client/react/redux';
import { getDefaultManagers, Controller } from '@data-client/react';
import { Provider } from 'react-redux';
import { createRoot } from 'react-dom/client';
import App from './App';

const managers = getDefaultManagers();
// be sure to include your other reducers here
const otherReducers = {};
const extraMiddlewares: Middleware[] = [];
// for instance, state serialized from the server
const initialState = {};

const { store, selector, controller } = prepareStore(
  initialState,
  managers,
  Controller,
  otherReducers,
  extraMiddlewares,
);

createRoot(document.body).render(
  <ExternalDataProvider
    store={store}
    selector={selector}
    controller={controller}
  >
    <Provider store={store}>
      <App />
    </Provider>
  </ExternalDataProvider>,
);
```

Then you'll want to use the [\<ExternalDataProvider />](https://dataclient.io/docs/api/ExternalDataProvider.md) instead of
[\<DataProvider />](https://dataclient.io/docs/api/DataProvider.md) and pass in the store and a selector function to grab
the Reactive Data Client specific part of the state.

> **Info: Note**
>
> You should only use ONE provider; nested another provider will override the previous.

> **Info: Note**
>
> Because `Reactive Data Client` [manager middlewares](https://dataclient.io/docs/api/Manager.md#middleware) return promises,
> all redux middlewares are placed after the [Managers](https://dataclient.io/docs/concepts/managers.md).
>
> If you need a middlware to run before the managers, you will need to wrap it in a [manager](https://dataclient.io/docs/api/Manager.md).
