SortableJS / react-sortablejs

React bindings for SortableJS
http://sortablejs.github.io/react-sortablejs/
MIT License
1.98k stars 206 forks source link

[bug] Dynamic group sorting #274

Closed Starlette closed 1 year ago

Starlette commented 1 year ago

Describe the bug I have a dynamic array that controls the groups and the items I'm sorting between each group.

interface ReviewerGroup {
    id: string;
    reviewers: IReviewer[];
}
// my TSX component 
const [groups, setGroups] = useState<ReviewerGroup[]>([]);
    const [reviewers, setReviewers] = useState<IUser[]>([new User()]);
    const group = 'reviewers';
    const animation = 150;

  useEffect(() => {
    async function fetchData() {
            setGroups([
                {
                    id: 'group1',
                    reviewers: [
                        {
                            id: 1,
                            first_name: 'fname 1',
                            last_name: 'lname 1'
                        }, {
                            id: 2,
                            first_name: 'fname 2',
                            last_name: 'lname 2'
                        }
                    ]
                },
                {
                    id: 'group2',
                    reviewers: [{
                        id: 3,
                        first_name: 'fname 3',
                        last_name: 'lname 3'
                    }, {
                        id: 4,
                        first_name: 'fname 4',
                        last_name: 'lname 4'
                    }]
                }
            ]);
        }
        fetchData();
  }, []);

    const setGroup = (e: IReviewer[], groupIndex: number) => {
        groups[groupIndex].reviewers = e;
        setGroups(groups);
    }

    return (
        <AdminLayout>
            <ReviewerOptionsMenu 
                title={(language.isEnglish) ? 'Reviewers' : 'Beoordelaars'} 
            />
            <Grid container spacing={2} className="mt-1">
                <Grid item xs={12} md={9}>
                    <Grid container spacing={2}>
                        {groups.map((items, groupIndex: number) => {
                            return (
                                <Grid key={items.id} item xs={12} md={4}>
                                    <ReactSortable 
                                        group={group} 
                                        key={items.id}
                                        tag={SortableWrapper} 
                                        list={items.reviewers}  
                                        setList={(e) => setGroup(e, groupIndex)}
                                        animation={animation}
                                    >
                                        {items.reviewers.map((user, itemIndex: number) => {
                                            return (
                                                <Chip  
                                                    clickable={true}
                                                    key={user.id}
                                                    avatar={
                                                        <Avatar {...stringAvatar(`${user.first_name} ${user.last_name}`)} />
                                                    } 
                                                    label={`${user.first_name} ${user.last_name}`} 
                                                />
                                            )
                                        })}
                                    </ReactSortable>
                                </Grid>
                            )
                        }

                        )}
                    </Grid>
                </Grid>

                <Grid 
                    item xs={12} md={3}
                    className="unassigned-list"
                >
                    <Paper variant="outlined" sx={{padding: 2}}>
                        <Typography variant="h5" marginBottom={2}>
                            Unassigned
                        </Typography>
                        <ReactSortable 
                            group={group} 
                            tag={SortableWrapper} 
                            animation={animation}
                            list={reviewers} 
                            setList={setReviewers} 
                        >
                            {reviewers.map(user => {
                                return (
                                    <Chip 
                                        key={user.id}
                                        clickable={true} 
                                        avatar={
                                            <Avatar {...stringAvatar(`${user.first_name} ${user.last_name}`)} />
                                        } 
                                        label={`${user.first_name} ${user.last_name}`}
                                        color="primary"
                                    />
                                )
                            })}
                        </ReactSortable>
                    </Paper>
                </Grid>
            </Grid>
        </AdminLayout>
    );

Expected behavior For the "" component to sort between groups.

Information When I console.log(groups) inside my setGroup() function, at the bottom, I get the correct data but it isn't updating in the template.

Versions - Look in your package.json for this information: react-sortable = ^6.1.4 react = ^18.2.0

Starlette commented 1 year ago

I got it working by changing one line: setGroups([...groups]);