Reputation: 5399
I am passing a list of objects to muuri-react
to display in a draggable grid layout and it works fine when I pass an explicitly defined list of objects, but when I use a redux selector to get the data it breaks even though it's the same data.
Here is an example that reproduces this: https://codesandbox.io/s/agitated-montalcini-rbdso?file=/src/components/pages/Notes.js
I render two Muuri grids one with with notes1
and one with notes2
which are identical objects, but somehow notes1
works fine and notes2
doesn't render properly (not draggable) and causes the error Invariant failed: The item has not been setted yet
if you try navigating to another tab like Reminders. I check that notes1
and notes2
are equal with lodash console log.
import React, { useEffect } from "react";
import { MuuriComponent } from "muuri-react";
import styled from "styled-components";
import { useSelector, useDispatch } from "react-redux";
import { fetchNotes } from "../../state/slices/notesSlice";
import _ from "lodash";
const Notes = () => {
const dispatch = useDispatch();
// Fetch notes
useEffect(() => {
dispatch(fetchNotes());
}, []);
let notes1 = [
{
id: "1",
title: "Title 1",
text:
"Text 1 - Est libero a lorem curabitur auctor at viverra ipsum id euismod condimentum dolor vel sit nullam libero nec"
},
{ id: "2", title: "Title 2", text: "Text 2 - Auctor dolor vitae nullam" },
{
id: "3",
title: "Title 3",
text:
"Text 3 - Viverra nunc enim adipiscing lorem laoreet id nec condimentum est odio dolor sagittis in libero nullam ipsum"
}
];
let notes2 = useSelector((state) => Object.values(state.notes.byId));
console.log("_.isEqual(notes1, notes2)?", _.isEqual(notes1, notes2));
return (
<StyledNotes>
<MuuriWrapper>
<MuuriComponent dragEnabled dragFixed>
{notes1.map((note, i) => (
<StyledNote key={i}>
<h3>{note.title}</h3>
<div>{note.text}</div>
</StyledNote>
))}
</MuuriComponent>
</MuuriWrapper>
<MuuriWrapper>
<MuuriComponent dragEnabled dragFixed>
{notes2.map((note, i) => (
<StyledNote key={i}>
<h3>{note.title}</h3>
<div>{note.text}</div>
</StyledNote>
))}
</MuuriComponent>
</MuuriWrapper>
</StyledNotes>
);
};
const MuuriWrapper = styled.div`
border: 1px solid black;
`;
const StyledNotes = styled.div`
padding: 30px;
`;
const StyledNote = styled.div`
border: 1px solid ${({ theme }) => theme.border};
border-radius: ${({ theme }) => theme.borderRadius};
background-color: ${({ theme }) => theme.background};
max-width: 250px;
min-width: 250px;
overflow-y: hidden;
padding: 15px;
margin: 15px;
&.muuri-item-dragging {
z-index: 1;
}
`;
export default Notes;
Upvotes: 0
Views: 507
Reputation: 14891
If you log notes2
, you will see that it changes from the length of 0 (start request), to the length of 3 (fully requested)
I see that the issue is due to the dynamic aspect of notes2
, while it seems that the murri lib will load well for the static one (notes1
)
So a quick fix could be to make sure to load MurriGrid after notes2
is fully requested, so it will avoid first time load for the init one (length of 0) then rerender to fully-loaded one (length of 3) - which caused unexpected behavior
{notes2.length && (
<MuuriWrapper>
<MuuriGrid>
{notes2.map((note, i) => (
<StyledNote key={i}>
<h3>{note.title}</h3>
<div>{note.text}</div>
</StyledNote>
))}
</MuuriGrid>
</MuuriWrapper>
)}
Upvotes: 1