# Хранилище сессионных данных
Сессионные данные - это ограниченные по сроку жизни и малого объема данные. \
Например, драфт формы заказа: значения частично заполненной формы имеет смысл сохранить и подставлять их автоматически как `initialValues` при последующих посещения страницы с формой. В этом примере значения формы - сессионные данные, которые буду автоматически удалены через N (задается во время сохранения) дней.

### Структура
Сессионное хранилище имеет структуру объекта, где ключ - строка, кратко описывающая содержимое хранилища, а значение - хранимые данные. \
Хранилище доступно как на сервере так и на клиенте. \
Доступ к хранилище на бэкенде осуществляются по puid (или по icookie, в случае отсутствия первого) пользователя, сделавшего запрос.

### Использование
Взаимодействие с сессионным хранилищем организованно через redux store. \
Для чтения из сессионного хранилища используется селектор `getSessionData<T>(state: RootState, key: string): T | undefined`, где `T` - тип, описывающий данные в хранилище. \
Для сохраненения в сессионное хранилище используется action `saveSessionData(Payload: IPayload)`, где
```
interface IPayload {
    key: string;
    data: unknown;
    // время жизни данных по заданному ключу в секундах,
    // undefined = без срока жизни, то есть сохранить навсегда
    ttl?: number;
    preserveState?: boolean;
}
```

### F.A.Q.
**Q: Как предовратить обновление store после изменения сессионных данных с помощью `saveSessionData(...)`?** \
A: В некоторых случаях бывает полезно сохранить значения сессионных данных в том виде, в котором они пришли с сервера. Например, `initialValues` формы заказа. Если менять `initialValues` на каждое изменение сессионных данных в store, то это может привести к нежелательным переинициализациям формы. Для таких случаев у action'a `saveSessionData` есть параметр `preserveState: boolean`.

**Q: Мне нужна сложная структура данных в сессионом хранилище / я хочу записывать значения на основе значений входящих properties. Как мне лучше сделать?** \
A: Используйте максимально простую структуру данных для хранения в сессионном хранилище, без сильных вложенностей. Для реализации вариативности сессионных данных на основе каких-либо параметров используйте динамическую генерацию ключей. Например,
```
const getSessionDataKey = orderId => `some-temp-order-data-${orderId}`

const mapStateToProps = (state, ownProps) => {
    const sessionData = getSessionData<number>(state, getSessionDataKey(ownProps.orderId));

    return { reactionsCount: sessionData || 0 };
}

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        onClick: count => dispatch(saveSessionData({
            key: getSessionDataKey(ownProps.orderId),
            data: count,
            ttl: 3600 // 1 hour
        })),
    };
};
```
