xyflow / xyflow

React Flow | Svelte Flow - Powerful open source libraries for building node-based UIs with React (https://reactflow.dev) or Svelte (https://svelteflow.dev). Ready out-of-the-box and infinitely customizable.
https://xyflow.com
MIT License
26.05k stars 1.67k forks source link

useEdgeState doesnt get updated when set edges inside provider #4750

Open dev-aly3n opened 1 month ago

dev-aly3n commented 1 month ago

What platform were you using when you found the bug?

Live code example

No response

Describe the Bug

we use this in the root component where react flow provider exist:

  const [nodes, setNodes] = useNodesState<CustomNode>([]);
  const [edges, setEdges] = useEdgesState<Edge>([]);

and then inside the custom node we have a button that add a new node and edge. everything works fine but the edges in the root. it doesnt get updated when we set new edges, however nodes get updated correctly I tried both useStore and useReactFlow functions to set the edge or add the edge and they didnt work.

Steps to reproduce the bug or issue

use react flow provider with useNodesState and useEdgesState and then try to set a new edge somewhere inside childrens. the root doesnt get updated

Expected behavior

it should get updated like nodes

Screenshots or Videos

No response

Additional context

No response

soheilous commented 1 month ago

Same here

justyouhappy commented 1 month ago

I also had the same problem. Within the custom node, the following methods were called:

const store = useStoreApi();
const state = store.getState();
state.setEdges([]);

The edges were updated successfully on the view, but onEdgesChange was not triggered, resulting in the edges of the associated node not being updated, which caused the deleted edges to be unable to reconnect.

peterkogo commented 1 month ago

Would you mind creating a small reproduction for this? You can create a new code sandbox at new.reactflow.dev/ts.

TrySpace commented 5 days ago

I have a similar issue when using this:

 const [nodes, setNodes, onNodesChange] = useNodesState<Node<NodeData>>(
    initialNodes || []
  )
  const [edges, setEdges, onEdgesChange] = useEdgesState<Edge<EdgeData>>(
    initialEdges || []
  )

in the main component as a child of the ReactFlowProvider. and passing the onXChange to the ReactFlow component.

Everything works as expected, but when i use const { setNodes } = useReactFlow() somewhere in a child, the some states only update when I drag around a node;

For example the getNodes() is not triggering the component to update when it in fact has:

See this example:

const DetachDescendantsButton: React.FC<{
  id: string
}> = ({ id }) => {
  const { getNodes, setNodes } = useReactFlow()
  const nodes = getNodes()

  const updateNodeInternals = useUpdateNodeInternals()
  const removeParentIdFromMultipleNodes = useCallback(
    (parentIdToRemove: string) => {
      setNodes((nodes) => {
        const parentNode = nodes.find((n) => n.id === parentIdToRemove)

        return nodes.map((node) => {
          if (node.parentId === parentIdToRemove) {
            return getNodeDataWithoutParentId(node, parentNode)
          }
          return node
        })
      })

      updateNodeInternals(id)
    },
    [setNodes]
  )

  const hasDescendants = useCallback(
    (nodeId: string) => {
      return nodes.some((node) => node.parentId === nodeId)
    },
    [nodes, getNodes]
  )

  return (
    hasDescendants(id) && (
      <Tooltip title="Detach all descendants">
        <IconButton
          size="small"
          onClick={(e) => {
            removeParentIdFromMultipleNodes(id)
          }}
        >
          <Icon>clear</Icon>
        </IconButton>
      </Tooltip>
    )
  )
}

And this button will only update when I move around the node where the button is in (in this case in the special Toolbar component), or when unmounting and rerendering the toolbar/button.

I initially thought it was the lack of updateNodeInternals() that I needed to trigger after doing setNodes(), but this doesn't help.

I should probably make this into a separate issue, but it seems related.

TrySpace commented 22 hours ago

This seems related to this: https://github.com/xyflow/xyflow/issues/4819