shiva shukla
shiva shukla

Reputation: 185

drop Specification of useDrop hooks api is always taking initial state instead of updated state

I am using react-dnd, on drop i want to dispatch an action with the updated local state value. I am updating the state on hover method provided by useDrop hooks. Problem: state is getting updated on hover but when drop method is called the value of the state is always the initial state. I have tried to replicate issue by taking example directly from react-dnd docs examples. Link to codesandbox with issue i am facing.

Dustbin.jsx

export const Dustbin = () => {
  const [test, setTest] = useState(false);
  const [{ canDrop, isOver }, drop] = useDrop(() => ({
    accept: ItemTypes.BOX,
    hover: () => {
      setTest(true);
    },
    drop: () => {
      console.log(test, "drop");
      return { name: "Dustbin" };
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop()
    })
  }));
  const isActive = canDrop && isOver;
  let backgroundColor = "#222";
  if (isActive) {
    backgroundColor = "darkgreen";
  } else if (canDrop) {
    backgroundColor = "darkkhaki";
  }
  console.log(test, "render");
  return (
    <div ref={drop} role={"Dustbin"} style={{ ...style, backgroundColor }}>
      {isActive ? "Release to drop" : "Drag a box here"}
    </div>
  );
};

As you can see I have the state with the name test with the initial value as false and I am updating the state on hover method. It is getting updated but on drop method you can see the console.log for the test which is always false(its initial state).

Expected Result: on drop method, value for the test must be true.

Thank you for the help, much appreciated.

Upvotes: 0

Views: 559

Answers (1)

garma
garma

Reputation: 101

Hi I've been throught the same issue for the past two days. Try this to solve your issue.

const [{ canDrop, isOver }, drop] = useDrop(() => ({
accept: ItemTypes.BOX,
hover: () => {
  setTest(true);
},
drop: () => {
  console.log(test, "drop");
  return { name: "Dustbin" };
},
collect: (monitor) => ({
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop()
})}),[test]);

Without [test] drop won't "see" the update state, but i don't really know why for now.

Upvotes: 1

Related Questions