大佬教程收集整理的这篇文章主要介绍了React - 在本地状态下更新二维数组而不更新显示网格中的每个组件,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用 react-window 的 VariableSizeGrID 来显示网格。
那个网格显示了一些格式化的数字,当你点击一个单元格时,你可以改变“原始”数字(没有格式),当焦点丢失时它会再次格式化(比如模糊)。这部分在 CodeSandBox 上似乎不太好用,但在我的本地应用上效果很好
在我的实际应用程序中,reportData 是从 API 中检索的,并且 delta 是动态创建的(以及行数、列数...)我尽可能地简化了代码专注于我的问题。
我将 reportData 和 delta 存储在本地组件状态(使用 UseState)中。在我的实际应用程序中,reportData 位于 redux 存储中,但这无关紧要。
我使用 (lodash) 以一种不可变的方式更新增量,但我有一个主要问题。
每次我在输入单元格中输入一个数字时,我只能输入一位数字(然后我失去焦点)。所以每输入一个数字,就会触发numberFIEld的onChange事件,这个调用Cell的onChange,调用DynamicReport的onChange然后更新delta的状态。然后状态更新会触发所有单元格的刷新(这就是为什么我无法输入/失去焦点)
我尝试添加一些去抖动,但这并没有真正解决我的问题。
在我的情况下,使用状态(如此本地状态)来存储我的 reportData 和 delta 是正确的方法吗?
我在 CodeSandBox 中创建了我的示例:
https://codesandbox.io/s/input-grid-example-zpotp
也许我的方法有根本缺陷,欢迎任何反馈/建议
请在下面找到我用于显示组件和报告/网格的代码
number-fIEld.tsx
import React,{ ReactElement,useState } from "react";
interface numberFIEldProps {
name: String;
value: number;
onChange: (event: React.ChangeEvent<HTMLinputElement>) => voID;
}
const numberFIEld = (props: numberFIEldProps): ReactElement => {
const [isEdiTing,setIsEdiTing] = useState(false);
const onChange = (event: React.ChangeEvent<HTMLinputElement>): voID => {
props.onChange(event);
};
const toFormattednumber = (number: number) => {
const formatter = new Intl.numberFormat("de-CH",{
style: "decimal",minimumFractionDigits: 2,maximumFractionDigits: 2
});
return formatter.format(number);
};
const toggleEdiTing = (): voID => {
console.log(
"numberFIEldDemo toggleEdiTing called for name: %s",props.name
);
setIsEdiTing(!isEdiTing);
};
const generateFIEld = (): ReactElement => {
if (isEdiTing) {
return (
<input
type="number"
name={props.namE}
value={props.value}
onChange={onChangE}
onBlur={toggleEdiTing}
classname="inputStd"
/>
);
} else {
return (
<div tabIndex={1} onFocus={toggleEdiTing}>
{toFormattednumber(props.value)}
</div>
);
}
};
return <div>{generateFIEld()}</div>;
};
export default numberFIEld;
report.tsx
// React
import React,useState } from "react";
// Lodash
import { cloneDeep } from "lodash";
import memoize from "memoize-one";
// react-window
import {
VariableSizeGrID as GrID,GrIDChildComponentProps
} from "react-window";
// FormatTing
import "./report.CSS";
// Own components
import numberFIEld from "./number-fIEld";
const ReportDemoState = (): ReactElement => {
const [wIDth,setWIDth] = useState(400);
const [height,setHeight] = useState(100);
const [reportData,setReportData] = useState([
[1,2,3,4],[5,6,7,8],[9,10,11,12]
]);
const [delta,setDelta] = useState([
[0,0],[0,0]
]);
const cell = ({
columnIndex,rowIndex,style,data
}: GrIDChildComponentProps): ReactElement => {
const [value,SETVALue] = useState(
reportData[rowIndex][columnIndex] + delta[rowIndex][columnIndex]
);
const onChange = (
event: React.ChangeEvent<HTMLinputElement>,rowIndex: number,columnIndex: number
): voID => {
data.onChange(event,columnIndeX);
};
const updateValue = (newValue: number) => {
SETVALue(newvalue);
};
return (
<div classname="GrIDItem" style={stylE}>
<numberFIEld
name={String(rowIndeX) + ":" + String(columnIndeX)}
value={value}
onChange={(event) => {
updateValue(number(event.target.value));
onChange(event,columnIndeX);
}}
></numberFIEld>
</div>
);
};
const createItemData = memoize((onChangE) => ({
onChange
}));
const DynamicReport = () => {
const columnWIDths = new Array(4).fill(true).map(() => 50);
const rowHeights = new Array(3).fill(true).map(() => 25);
const onChange = (
event: React.ChangeEvent<HTMLinputElement>,columnIndex: number
) => {
let newDelta = cloneDeep(delta);
newDelta[rowIndex][columnIndex] =
number(event.target.value) - number(reportData[rowIndex][columnIndex]);
setDelta(newDelta);
};
const itemData = createItemData(onChangE);
return (
<GrID
classname="GrID"
columnCount={4}
columnWIDth={(indeX) => columnWIDths[index]}
height={height}
rowCount={3}
rowHeight={(indeX) => rowHeights[index]}
wIDth={wIDth}
itemData={itemData}
>
{Cell}
</GrID>
);
};
return (
<div classname="full-page">
<p>Report Demo State</p>
<DynamicReport />
</div>
);
};
export default ReportDemoState;
report.CSS
.GrID {
border: 1px solID #d9dddd;
}
.GrIDItem {
display: flex;
align-items: center;
justify-content: center;
}
.inputStd {
wIDth: 50px;
}
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
以上是大佬教程为你收集整理的React - 在本地状态下更新二维数组而不更新显示网格中的每个组件全部内容,希望文章能够帮你解决React - 在本地状态下更新二维数组而不更新显示网格中的每个组件所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。