Skip to content

Commit

Permalink
Merge pull request #2165 from adumesny/master
Browse files Browse the repository at this point in the history
more react demo example fixes
  • Loading branch information
adumesny authored Jan 14, 2023
2 parents 168b944 + aa7355e commit 6508df3
Showing 1 changed file with 17 additions and 28 deletions.
45 changes: 17 additions & 28 deletions demo/react-hooks-controlled-multiple.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h2>Controlled stack</h2>

<script type="text/babel">
/***********************************************************************************************************/
/********************************* NOT IDEAL - see comments below line 111) ********************************/
/********************************* NOT IDEAL - see comments below line ~96) ********************************/
/***********************************************************************************************************/

const { useState, useEffect, useLayoutEffect, createRef, useRef } = React
Expand All @@ -33,7 +33,7 @@ <h2>Controlled stack</h2>
//
// Controlled example
//
const ControlledStack = ({ items, addItem, removeItem, changeItems }) => {
const ControlledStack = ({ items, addItem, changeItems }) => {
const refs = useRef({})
const gridRef = useRef()
const gridContainerRef = useRef(null)
Expand Down Expand Up @@ -61,34 +61,28 @@ <h2>Controlled stack</h2>
.on('added', (ev, gsItems) => {
if (grid._ignoreCB) return;
// remove the new element as React will re-create it again (dup) once we add to the list or we get 2 of them with same ids but different DOM el!
// TODO: this is really not ideal - we shouldn't mix React templating with GS making it own edits as those get out of sync! see comment below @111.
// TODO: this is really not ideal - we shouldn't mix React templating with GS making it own edits as those get out of sync! see comment below ~96.
gsItems.forEach(n => {
grid.removeWidget(n.el, true, false); // true=remove DOM, false=don't call use back!
// can't pass n directly even though similar structs as it has n.el.gridstackNode which gives JSON error for circular write.
addItem({id:n.id, x:n.x, y:n.y, w:n.w, h:n.h});
});
})
.on('removed', (ev, gsItems) => {
/* Looks like a bug in GridStack */
const dirtyNodes = grid.engine.getDirtyNodes();
if (dirtyNodes !== undefined && dirtyNodes.length !== 0) {
const newItems = grid.save(false);
changeItems(newItems);
}

if (grid._ignoreCB) return;
gsItems.forEach(n => removeItem(n.id));
})
.on('change', (ev, gsItems) => {
const newItems = grid.save(false);
.on('removed change', (ev, gsItems) => {
// synch our version from GS....
// Note: we could just update those few items passed but save() is fast and it's easier to just set an entire new list
// and since we have the same ids, React will not re-create anything...
const newItems = grid.save(false); // saveContent=false
changeItems(newItems);
})
// addEvents(grid, i);
} else {
//
// update existing grid layout, which is optimized to updates only diffs (will add new/delete items for examples)
// update existing GS layout, which is optimized to updates only diffs and add new/delete items as well
//
const grid = gridRef.current;
const layout = items.map((a) =>
// use exiting nodes (which will skip diffs being the same) else new elements Widget but passing the React dom .el so we know what to makeWidget() on!
refs.current[a.id].current.gridstackNode || {...a, el: refs.current[a.id].current}
);
grid._ignoreCB = true; // hack: ignore added/removed since we're the one doing the update
Expand All @@ -100,14 +94,15 @@ <h2>Controlled stack</h2>

return (
// ********************
// NOTE: constructing DOM grid items in template when gridstack is also allowed editing (dragging between grids, or adding/removing from say a toolbar)
// NOTE: constructing DOM grid items in template when gridstack is also allowed creating (dragging between grids, or adding/removing from say a toolbar)
// is NOT A GOOD IDEA as you end up fighting between gridstack users' edits and your template items structure which are not in sync.
// At best, you end up re-creating widgets DOM (from React template) and all their content & state after a widget was inserted/re-parented by the user.
// a MUCH better way is to let GS create React components using it's API/user interactions, with only initial load() of a stored layout.
// see the upcoming Angular component wrapper that does that instead (lib author uses Angular). TBD creating React equivalent...
// See the Angular component wrapper that does that: https://github.com/gridstack/gridstack.js/tree/master/demo/angular/src/app (lib author uses Angular)
// ...TBD creating React equivalent...
//
// Also templating forces you to spell out the 12+ attributes GS supports (only x,w,w,h done below) instead of passing a option structure that supports everything
// is not robust as things get added, and pollutes the DOM attr for default/missing entries, vs optimized code in GS.
// Also templating forces you to spell out the 15+ GridStackWidget attributes (only x,y,w,h done below), instead of passing an option structure that
// supports everything, is not robust as things get added and pollutes the DOM attr for default/missing entries, vs the optimized code in GS.
// ********************
<div style={{ width: '100%', marginRight: '10px' }}>
<div className="grid-stack" ref={gridContainerRef}>
Expand All @@ -130,7 +125,7 @@ <h2>Controlled stack</h2>

const ControlledExample = () => {
const [items1, setItems1] = useState([{ id: 'item-1-1', x: 0, y: 0, w: 2, h: 2 }, { id: 'item-1-2', x: 2, y: 0, w: 2, h: 2 }])
const [items2, setItems2] = useState([{ id: 'item-2-1', x: 0, y: 0, w: 1, h: 1 }, { id: 'item-2-2', x: 0, y: 1, w: 1, h: 1 }, { id: 'item-2-3', x: 1, y: 0, w: 1, h: 1 }])
const [items2, setItems2] = useState([{ id: 'item-2-1', x: 0, y: 0 }, { id: 'item-2-2', x: 0, y: 1 }, { id: 'item-2-3', x: 1, y: 0 }])

return (
<div>
Expand All @@ -149,9 +144,6 @@ <h2>Controlled stack</h2>
addItem={(item) => {
setItems1(items => [...items, item])
}}
removeItem={(id) => {
setItems1(items => items.filter(i => i.id !== id))
}}
changeItems={(items) => setItems1(items)}
/>
</div >
Expand All @@ -161,9 +153,6 @@ <h2>Controlled stack</h2>
addItem={(item) => {
setItems2(items => [...items, item])
}}
removeItem={(id) => {
setItems2(items => items.filter(i => i.id !== id))
}}
changeItems={(items) => setItems2(items)}
/>
</div>
Expand Down

0 comments on commit 6508df3

Please sign in to comment.