I am building a functional component that should render a sortable component (ReactSortable) with computed array (layers array) that comes from a mobx store using react-sortablejs. The component renders when the apps load, but when resorting the array by dragging and dropping elements, I get the following error:
mobx.module.js:89 Uncaught Error: [mobx] Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an action if this change is intended. Tried to modify: LayerStore@23.layersRegistry.9f332395-6bfe-4c3f-a496-8804e1dec490.chosen?
Actually, the layers array is computed from layersRegistry Map observable in the store as the code below shows, but when sorting the layers, I am not changing the layersRegistry observable; that’s why I got confused from the error.
Whats the problem in this case, and how can I resolve it such that when I resort the layers (by drag drop) the layers variable in the store or the layersRegistry Map observable is updated based on the sorting? Here the code for the component
import React, { useContext, useEffect, Fragment, useState } from "react";
import { RootStoreContext } from "../../../app/stores/rootStore";
import { observer } from "mobx-react-lite";
import LayerListItem from "./LayerListItem";
import { ReactSortable } from "react-sortablejs";
export const LayersDashboard = () => {
const rootStore = useContext(RootStoreContext);
const { layers, loadLayers } = rootStore.layerstore;
useEffect(() => {
loadLayers();
}, [loadLayers]);
const [items, setItems] = useState(layers);
return (
<Fragment>
<ReactSortable list={layers} setList={setItems}>
{layers.map((layer) => (
<LayerListItem key={layer.id} layer={layer} />
))}
</ReactSortable>
</Fragment>
);
};
export default observer(LayersDashboard);
Here is the code for the store
import { observable, action, runInAction, computed } from "mobx";
import agent from "../api/agent";
import { RootStore } from "./rootStore";
import { ILayer } from "../models/Layer";
export default class LayerStore {
rootStore: RootStore;
constructor(rootStore: RootStore) {
this.rootStore = rootStore;
}
@observable layersRegistry = new Map();
@computed get layers() {
return Array.from(this.layersRegistry.values());
}
@action loadLayers = async () => {
try {
const layers = await agent.Layers.list();
runInAction(() => {
layers.forEach((layer) => {
this.layersRegistry.set(layer.id, layer);
});
});
} catch (error) {
runInAction(() => {
console.log("error");
});
}
};
}