SortableJS/react-sortablejs

[bug] Uncaught TypeError: Cannot assign to read only property 'chosen' of object '#<Object>' when using 6.0.4 with immutable data

julienben opened this issue · 10 comments

Hi!

Everything works fine for me in v6.0.3 but as soon as I use 6.0.4 or above, I get the error mentioned above.

I've tried 6.1.x as well but the issue is still present. It seems to be due to the changes made in this commit: 362cbd5

Spreading (as done in 6.0.3) seems to work fine but Object.assign won't work.

Note:

  • My data is from immer so that could be related.
  • It seems kind of strange that react-sortable (or sortable?) is adding extra keys to the list of objects passed into the props. It feels like it could create bugs easily.

To Reproduce
Steps to reproduce the behavior:

  1. I don't have a public repo to share but it's the exact same issue described in #228. The solution described there didn't work for me.

Expected behavior
For Sortable to work beautifully just like in 6.0.3 ;)

Information
This is required. Issues without this critical information will be closed.

Versions - Look in your package.json for this information:
react-sortable = 6.0.4
react = 17.0.2

Additional context
I'm doing nesting and it works flawlessly 🤷‍♂️

If anyone comes this way, I was able to fix this issue on my side with:

import { setAutoFreeze } from 'immer';

setAutoFreeze(false);

I think the point that the library shouldn't modify the state it receives should still stand... It should only read it.

I'm having the same issue using data from my Redux store on v6.1.4.

wpsix commented

@ecfaria works with version 6.0.3

I'm having the same issue using data from my Redux store on v6.1.4.

Same issue using Redux with Redux Toolkit here, with react-sortablejs v6.1.4
The immer fix is not working for me.

I am seeing the same issue in 6.1.1 while using React 18 and Recoil. Also, this only shows when React.StrictMode is used

I am seeing the same issue in 6.1.1 while using React 18 and Recoil. Also, this only shows when React.StrictMode is used

Also React 18 + Recoil + StrictMode, is there any solution?

Yeah, I am seeing the same issue with zustand and react-sortablejs v6.1.4.

Any fix?

same issue...
I use a wrapper component to prevent state mutation in the store:

import { useMemo } from "react";
import {
  ItemInterface,
  ReactSortable,
  ReactSortableProps,
  Sortable as SortableLib,
  Store,
} from "react-sortablejs";

function arrayEquals(a: any, b: any) {
  return (
    Array.isArray(a) &&
    Array.isArray(b) &&
    a.length === b.length &&
    a.every((val, index) => val === b[index])
  );
}

export default function Sortable<T extends ItemInterface>({
  children,
  list,
  setList,
  ...rest
}: ReactSortableProps<T>) {
  const mutableList = useMemo(() => {
    return list.map((item) => ({ ...item }));
  }, [list]);

  function handleList(updatedList: T[], sortable: SortableLib | null, store: Store) {
    if (
      !arrayEquals(
        updatedList.map((l) => l.id),
        mutableList.map((l) => l.id),
      )
    ) {
      setList(updatedList, sortable, store);
    }
  }

  return (
    <ReactSortable list={mutableList} setList={handleList} {...rest}>
      {children}
    </ReactSortable>
  );
}

Same issue here. The funny thing is (not 100% sure) that this issue might be fixed in the unpublished v6.1.5. (almost a year ago) since this commit looks like is the solution for exactly this. Not sure why it's not published 🤷‍♂️