我有一个 QQTable
函数组件,其中包含 1 个 QQTableBody
。
而 QQTableBody
函数组件包含多个 QQRow
函数组件。
每个 QQRow
功能组件都有多个 QQCell
功能组件。
这是 QQTable
代码片段:
import {useCallback,useContext,useEffect, useState} from 'react';
import QQTableBody from './QQTableBody';
import QQTableHeader from './QQTableHeader';
import Roster from '../../utils/Roster';
import RosterWebContext from '../../utils/RosterWebContext';
import SelectedRegion from '../../utils/SelectedRegion';
import SelectedRegionUtil from '../../utils/SelectedRegionUtil';
export default function QQTable(props){
const[activeShiftInfoList,setActiveShiftInfoList]=useState();
const [rosterData,setRosterData]=useState();
const [selectedRegion,setSelectedRegion]=useState(new SelectedRegion());
let componentList=[];
let systemParam=props.systemParam;
let mouseUp=useCallback(()=>{
console.log("mouse up");
console.log(selectedRegion.inSelectMode);
SelectedRegionUtil.endSelect(selectedRegion,setSelectedRegion);
},[selectedRegion]);
useEffect(()=>{
const getData = async () => {
console.log("getData() is triggered");
.................................
let roster = new Roster();
temp = await roster.getAllActiveShiftInfo();
setActiveShiftInfoList(temp);
temp= await roster.get(props.rosterMonth.getFullYear(),props.rosterMonth.getMonth()+1);
setRosterData (temp);
document.addEventListener('mouseup',mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp)
}
}
getData();
},[props.rosterMonth]);
let contextValue={}
if (rosterData){
contextValue={
activeShiftInfoList,
rosterData,
selectedRegion,
setHightLightCellIndex,
setRosterData,
setSelectedRegion,
}
..........
componentList.push(<QQTableBody key="body"/>);
}
return(
<RosterWebContext.Provider value={contextValue}>
<table id="rosterTable">
{componentList}
</table>
</RosterWebContext.Provider>
)
}
这是 QQCell
片段:
import {useContext} from 'react';
import RosterWebContext from '../../utils/RosterWebContext';
import SelectedRegionUtil from '../../utils/SelectedRegionUtil';
export default function QQCell(props){
let cssClassName="QQ";
let {
selectedRegion,
setSelectedRegion
} = useContext(RosterWebContext);
function mouseDownHandler(e){
SelectedRegionUtil.startSelect(e.target,selectedRegion,setSelectedRegion);
}
function mouseEnterHandler(e){
props.onMouseEnter(e);
SelectedRegionUtil.updateSelect(e.target, selectedRegion,setSelectedRegion);
}
return (
<td
className={cssClassName}
contentEditable={true}
onMouseDown={mouseDownHandler}
onMouseEnter={mouseEnterHandler}
suppressContentEditableWarning={true}>
{props.children}
</td>
)
}
还有 SelectedRegionUtil
的片段:
export default class SelectedRegionUtil{
.....................
static endSelect(selectedRegion,setSelectedRegion){
if (selectedRegion.inSelectMode){
let temp=JSON.parse(JSON.stringify(selectedRegion));
temp.inSelectMode=false;
setSelectedRegion(temp);
}
}
............................................
static startSelect(theCell,selectedRegion,setSelectedRegion){
let row=theCell.parentElement;
let temp=JSON.parse(JSON.stringify(selectedRegion));
temp.firstX=theCell.cellIndex;
temp.firstY=row.rowIndex;
temp.minX=theCell.cellIndex;
temp.minY=row.rowIndex;
temp.maxX=theCell.cellIndex;
temp.maxY=row.rowIndex;
temp.inSelectMode=true;
console.log("temp="+JSON.stringify(temp));
setSelectedRegion(temp);
}
..........................................................
static updateSelect(theCell,selectedRegion,setSelectedRegion){
if (selectedRegion.inSelectMode){
let cellIndex=theCell.cellIndex;
let isChanged=false;
let newMaxX=selectedRegion.maxX,newMinX=selectedRegion.minX;
let newMaxY=selectedRegion.maxY,newMinY=selectedRegion.minY;
let row=theCell.parentElement;
let rowIndex=row.rowIndex;
if (cellIndex<selectedRegion.firstX)
{
newMinX=cellIndex;
isChanged=true;
}
else
{
if (cellIndex>selectedRegion.firstX)
{
newMaxX=cellIndex;
isChanged=true;
}
else
{
newMinX=selectedRegion.firstX;
newMaxX=selectedRegion.firstX;
isChanged=true;
}
}
if (rowIndex>selectedRegion.firstY)
{
newMaxY=rowIndex;
isChanged=true;
}
else
{
if (rowIndex<selectedRegion.firstY)
{
newMinY=rowIndex;
isChanged=true;
}
else
{
newMinY=selectedRegion.firstY;
newMaxY=selectedRegion.firstY;
isChanged=true;
}
}
if (isChanged){
//console.log("isChanged=true");
let temp=JSON.parse(JSON.stringify(selectedRegion))
temp.minX=newMinX;
temp.maxX=newMaxX;
temp.minY=newMinY;
temp.maxY=newMaxY;
setSelectedRegion(temp);
}
}
}
}
最后,SelectedRegion
片段:
export default class SelectedRegion{
constructor(){
this.firstX=-1;
this.firstY=-1;
this.inSelectMode=false;
this.minX=-1;
this.minY=-1;
this.maxX=-1;
this.maxY=-1;
}
}
上面的代码片段显示了 QQCell 功能组件调用 SelectedRegionUtil 将状态变量 selectedRegion.inSelectMode 更改为 true。
不幸的是,QQTable
中的 mouseUp 函数总是显示 selectedRegion.inSelectMode
的值为 false。
我曾尝试将 mouseUp 函数移动到 useEffect
函数中,但结果是一样的。
你会如何解决它?
或者有什么包可以只在表的一个区域而不是整个表中执行选择、复制和粘贴功能?
答案 0 :(得分:0)
最后,在 QQTable
组件中,我从 useEffect
钩子中删除了以下代码:
document.addEventListener('mouseup',mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp)
}
然后在 useEffect
组件中添加另一个 QQTable
钩子:
useEffect(()=>{
document.addEventListener('mouseup',mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp)
}
},[mouseUp])
它按我的预期工作。