xyflow: Flow doesn't re-render on elements state change

`const Body = () => {

const addChild = (parentId) => {
    setParent(parentId)
    setPopup(true)
}
let {chart, insertNode} = useChart(departmentData, addChild)
const onLoad = (reactFlowInstance) => reactFlowInstance.setTransform({x: 10, y: 10, zoom: 0.8})
const [popup, setPopup] = useState(false)
const [parent, setParent] = useState()
const reff = useClickOutside(() => setPopup(false))
console.log("Body render")

return (
    <Container>
        <FlowContainer>
            {chart.map(item => item.id).join(" ")}
            <FlowBorder>
                <ReactFlow 
                    onLoad={onLoad}
                    elements={chart} 
                    nodesDraggable={true} 
                    nodesConnectable={false}
                    nodeTypes={{department: DepartmentNode}}
                    >
                </ReactFlow>
                {popup && <PopupContainer>
                    <AddChildForm reff={reff} chart={chart} parentId={parent} onAdd={(data) => {setPopup(false); insertNode(data)}}/>
                </PopupContainer>}
            </FlowBorder>
        </FlowContainer>
    </Container>
)

}` “chart” is a React state returned from a custom hook, basically I’m trying to add new node to chart through a form. The text below “FlowContainer” renders fine but “ReactFlow” stays the same, the same nodes and edges from initial.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 21 (8 by maintainers)

Most upvoted comments

Fixed by initializing dagreGraph on each function call:

const getLayoutedElements = (elements: FlowElement[]) => {
  const dagreGraph = new dagre.graphlib.Graph();
  dagreGraph.setDefaultEdgeLabel(() => ({}));
  dagreGraph.setGraph({ rankdir: "TB" });
  const width = 200;
  const height = 100;
  [...]
};

Fixed by initializing dagreGraph on each function call:

const getLayoutedElements = (elements: FlowElement[]) => {
  const dagreGraph = new dagre.graphlib.Graph();
  dagreGraph.setDefaultEdgeLabel(() => ({}));
  dagreGraph.setGraph({ rankdir: "TB" });
  const width = 200;
  const height = 100;
  [...]
};

it works!

My workaround for this problem! Change from

setChart(chartRef.current.nodes)

to

setChart([])
setTimeout(() => {
    setChart(chartRef.current.nodes)
}, 1);
}