ReactJS中如何在FunctionB中使用FunctionA内声明的变量?
在React组件中让FunctionB使用FunctionA变量的解决方案
我看了你的代码,核心需求是让同一组件里的FunctionB能拿到FunctionA中声明的dataDest和dataOrig变量,这里给你梳理几个可行的调整方案,最直接的就是通过函数参数传递,另外也可以根据场景用组件状态共享:
方案一:直接通过函数参数传递变量(最推荐)
这是最符合函数作用域逻辑的方式,把FunctionA里需要共享的变量都作为参数传给FunctionB,同时还要注意几个细节:
- 先补全FunctionA里的
dataOrig变量声明(你的代码里调用FunctionB时传了这个变量,但没看到定义,会导致undefined) - 把FunctionB里用到的
channelDest、numcartDest也一起传过去,因为这些变量只存在于FunctionA的作用域里
修改后的FunctionA代码:
const FunctionA = (e) => { setPopupOpen(true) e.preventDefault() // 当前容器的数据 let dataDest = e.currentTarget.getAttribute('data') let jdataDest = JSON.parse(dataDest) let channelDest = jdataDest.channel let numcartDest = jdataDest.data.NUM_CART // 补上dataOrig的定义(这里假设你是从拖拽数据中获取,根据实际逻辑调整) let dataOrig = e.dataTransfer.getData("dataOrigKey") let jdataOrig = dataOrig ? JSON.parse(dataOrig) : null let dataItem = jdataOrig?.data // 当前拖拽项的数据 let tot = e.dataTransfer.getData("mydatabrowser") if (tot) { // 从浏览器外部拖拽 let dataItem = JSON.parse(tot) console.log(dataItem) console.log("drop from browser", dataItem) // 执行外部拖拽操作 InsertItem(callbackDrag, props.ddo, dataItem.val.guid, channelDest, numcartDest, dataItem) } else { // 容器间内部拖拽:传递所有需要的变量给FunctionB FunctionB(dataOrig, dataDest, channelDest, numcartDest, dataItem) } e.dataTransfer.clearData() }
修改后的FunctionB代码:
const FunctionB = (dataOrig, dataDest, channelDest, numcartDest, dataItem) => { // 先校验必要参数是否存在 if (!dataOrig || !dataDest) return if (dndReplace) { ReplaceItem(callbackDrag, props.ddo, dataItem?.GUID_ITEM, channelDest, numcartDest, dataItem) } else { InsertItem(callbackDrag, props.ddo, dataItem?.val?.guid, channelDest, numcartDest, dataItem) } }
方案二:用组件状态共享变量(适合多场景复用)
如果dataDest、dataOrig这些变量不仅要在这两个函数间共享,还需要在组件的其他地方使用,可以把它们存在组件的状态中:
示例代码:
// 在组件顶部声明状态 const [sharedDragData, setSharedDragData] = useState({ dataDest: null, dataOrig: null, channelDest: null, numcartDest: null, dataItem: null }) const FunctionA = (e) => { setPopupOpen(true) e.preventDefault() // 当前容器的数据 let dataDest = e.currentTarget.getAttribute('data') let jdataDest = JSON.parse(dataDest) let channelDest = jdataDest.channel let numcartDest = jdataDest.data.NUM_CART // 补上dataOrig的定义 let dataOrig = e.dataTransfer.getData("dataOrigKey") let jdataOrig = dataOrig ? JSON.parse(dataOrig) : null let dataItem = jdataOrig?.data // 更新状态,把需要共享的变量存进去 setSharedDragData({ dataDest, dataOrig, channelDest, numcartDest, dataItem }) // 当前拖拽项的数据 let tot = e.dataTransfer.getData("mydatabrowser") if (tot) { // 外部拖拽逻辑不变 let dataItem = JSON.parse(tot) console.log(dataItem) console.log("drop from browser", dataItem) InsertItem(callbackDrag, props.ddo, dataItem.val.guid, channelDest, numcartDest, dataItem) } else { // 直接调用FunctionB,不用传参 FunctionB() } e.dataTransfer.clearData() } const FunctionB = () => { // 从状态中取出需要的变量 const { dataOrig, dataDest, channelDest, numcartDest, dataItem } = sharedDragData if (!dataOrig || !dataDest) return if (dndReplace) { ReplaceItem(callbackDrag, props.ddo, dataItem?.GUID_ITEM, channelDest, numcartDest, dataItem) } else { InsertItem(callbackDrag, props.ddo, dataItem?.val?.guid, channelDest, numcartDest, dataItem) } }
总的来说,方案一的参数传递是最直接且高效的,适合只在两个函数间共享变量的场景;如果变量需要在组件多个地方复用,再考虑方案二的状态共享。
内容的提问来源于stack exchange,提问作者Marco Vanin
相关产品推荐
相关产品推荐

