为什么react-dnd useDrop hook中的回调函数无法更新父组件状态?
Why callback function in react-dnd useDrop hook can't update parent component state?
dnd Hook Api,想在useDrop drop
函数中调用父组件回调函数更新状态,
但是我只能从初始状态更新父状态。
举个例子,无论我如何将div放到dropTarget,计数总是更新为1,但是当点击按钮时,它可以像我预期的那样更新,为什么会这样?以及如何解决这个问题?
https://codesandbox.io/s/reactdndexample3-gpc61?fontsize=14
import React, { useState } from 'react';
import { __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ as dnd, DropTarget } from 'react-dnd'
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend'
const { useDrag,useDrop } = dnd
function HookTest(props) {
const [count,setCount] = useState(0);
return (
<div>
<button onClick={()=>{setCount(count + 1)}}>clickToAdd</button>
<DropDiv addCount={()=>{setCount(count + 1)}}></DropDiv>
<DragDiv></DragDiv>
<div>{count}</div>
</div>
);
}
export default DragDropContext(HTML5Backend)(HookTest)
function DropDiv(props) {
const [collectedProps, drop] = useDrop({
accept:"widget",
hover:(item,monitor) => {
},
drop:(item,monitor)=>props.addCount(),
collect:(monitor) => {
return {
isOver:monitor.isOver({shallow: true}),
}
}
})
return (
<div ref={drop} style={{width:"100px",height:"100px",background:"blue"}}>
dropTarget
</div>
)
}
function DragDiv(props) {
const [dragSource,drag] = useDrag({
item: {type:"widget"},
collect: monitor => ({
opacity: monitor.isDragging() ? 0.4 : 1,
}),
})
return (
<div ref={drag} style={{width:"100px",height:"100px",background:"red"}}>
DragSource
</div>
)
}
更新不起作用,因为在为 onClick
和 addCount
创建的函数的上下文中,count
始终具有值 0
.
我建议您使用 setCount
的替代语法,并传递一个函数,该函数获取先前的状态作为参数,returns 更新后的状态。
<button onClick={()=>{setCount(prevCount => prevCount + 1)}}>clickToAdd</button>
<DropDiv addCount={()=>{setCount(prevCount => prevCount + 1)}}></DropDiv>
dnd Hook Api,想在useDrop drop
函数中调用父组件回调函数更新状态,
但是我只能从初始状态更新父状态。
举个例子,无论我如何将div放到dropTarget,计数总是更新为1,但是当点击按钮时,它可以像我预期的那样更新,为什么会这样?以及如何解决这个问题?
https://codesandbox.io/s/reactdndexample3-gpc61?fontsize=14
import React, { useState } from 'react';
import { __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ as dnd, DropTarget } from 'react-dnd'
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend'
const { useDrag,useDrop } = dnd
function HookTest(props) {
const [count,setCount] = useState(0);
return (
<div>
<button onClick={()=>{setCount(count + 1)}}>clickToAdd</button>
<DropDiv addCount={()=>{setCount(count + 1)}}></DropDiv>
<DragDiv></DragDiv>
<div>{count}</div>
</div>
);
}
export default DragDropContext(HTML5Backend)(HookTest)
function DropDiv(props) {
const [collectedProps, drop] = useDrop({
accept:"widget",
hover:(item,monitor) => {
},
drop:(item,monitor)=>props.addCount(),
collect:(monitor) => {
return {
isOver:monitor.isOver({shallow: true}),
}
}
})
return (
<div ref={drop} style={{width:"100px",height:"100px",background:"blue"}}>
dropTarget
</div>
)
}
function DragDiv(props) {
const [dragSource,drag] = useDrag({
item: {type:"widget"},
collect: monitor => ({
opacity: monitor.isDragging() ? 0.4 : 1,
}),
})
return (
<div ref={drag} style={{width:"100px",height:"100px",background:"red"}}>
DragSource
</div>
)
}
更新不起作用,因为在为 onClick
和 addCount
创建的函数的上下文中,count
始终具有值 0
.
我建议您使用 setCount
的替代语法,并传递一个函数,该函数获取先前的状态作为参数,returns 更新后的状态。
<button onClick={()=>{setCount(prevCount => prevCount + 1)}}>clickToAdd</button>
<DropDiv addCount={()=>{setCount(prevCount => prevCount + 1)}}></DropDiv>