【发布时间】:2020-03-11 18:25:46
【问题描述】:
总的来说,我对 React/开发相对较新(大约 5 个月),我偶然发现了以下问题,这让我非常抓狂。我想知道我是否愚蠢并且错过了一个基本概念,或者这是更深层次的东西。
给你一些关于我的项目的背景以及这个问题是如何出现的:
我正在构建一个计算器应用程序,非常类似于您在 Google 上搜索“计算器”时获得的应用程序。我正在尝试编写一个函数,每次用户单击计算器上的按钮时,都会将与显示相关的所有内容保存为对象,并将该对象添加到保持状态的数组中,该数组的整个“输入历史”计算器。这样,当用户想逐个删除显示值时,计算器只需返回输入历史数组中的一个索引,并及时返回到之前的设置。这样计算器仍然可以在删除(指数、不匹配的括号等)时显示漂亮的动态渲染样式,而无需编写非常长、复杂且几乎可以肯定有错误的删除函数。
为了实现这一点,我告诉我的程序,在每次状态更改(我保留显示值的位置)后,将当前设置和显示添加到输入历史数组中。我选择将此函数放在 componentDidUpdate 方法中,并确保仅在 this.state.inputHistUpdated 为 false 时调用它来确保它只触发一次,每次将某些内容添加到显示时都会发生这种情况。
这是我的函数,在 componentDidUpdate() 方法中:
if (!this.state.inputHistUpdated) {
let newInputHist = {
currentMath : this.state.currentMath,
exponentCount : this.state.exponentCount,
spanStr : this.state.spanStr,
rightParensArr : this.state.rightParensArr,
}
console.log(newInputHist);
this.setState((prevState) => {
return {
inputHistory : [...prevState.inputHistory, newInputHist],
inputHistUpdated : true
}
})
}
输入对象中的每个值都可能受到用户输入内容的影响,并以某种形式出现在显示中。
问题是这样的
用户在计算器中输入一个 5。 newInputHist 记录单个对象,其 currentMath 值为 5。(这是预期的)。 React DevTools 还显示 this.state.inputHist 是一个对象的数组,其 currentMath 值也是 5(如预期的那样)。 这就是问题所在:假设用户在计算器中输入了“+”。 newInputHist 记录一个 currentMath 值为 '5 +' 的对象,这是正确的,并且已将一个新对象添加到 this.state.inputHist 中,其 currentMath 值也是 '5 +' 但另一个元素的 currenMath 值我们之前添加的那个数组也已从“5”更改为“5 +”。每次我更新显示时都会发生这种情况; this.state.inputHist 数组中每个对象的 currentMath 属性都会更新为 CURRENT currentMath 属性,而不是保存它最初拥有的属性。
这对我来说完全没有意义。我尝试过将对象连接到数组的其他方法,并在 Google 和 SO 上下搜索以寻找解决方案,但找不到任何有用的东西。
如果您需要更多信息/代码,请告诉我您认为可能发生的情况。我想给你足够的背景,等等,所以你可以回答我的问题而不添加任何无关的东西,但如果我不能随意这么说。
这里有更多代码:
此函数将数字/操作/所有内容添加到显示中
addToDisplay(input) {
this.setState((prevState) => {
let calcArr = prevState.newCalc ? [] : prevState.currentMath
if (prevState.lastInput=== '□') {
calcArr.pop();
}
if (prevState.lastInput === ' - ' && /[×\-÷\+]/.test(prevState.currentMath[prevState.currentMath.length-2])) {
calcArr[calcArr.length-1] = ' -'
}
calcArr.push(input)
return {
currentMath : calcArr,
calcActive : true,
lastInput : input,
newCalc : false,
inputHistUpdated : false
}
});
}
这两个函数处理显示中动态呈现的 UI——当用户输入左括号时添加特殊样式的右括号,当用户在指数中上升一级时添加必要的不可见 </spans>,该指数具有不同的风格
rightParensFunc() {
let styledParens = `<span class='parens exp-${this.state.exponentCount}'>)</span>`;
this.setState((prevState) => {
return {
rightParensArr : [styledParens, ...prevState.rightParensArr],
inputHistUpdated : false
}
});
}
spanFunc() {
let counter = this.state.exponentCount;
let spans = '';
while (counter > 0) {
spans = spans + '</span>';
counter--;
};
this.setState({
spanStr : spans,
inputHistUpdated : false
})
}
然后这是我的构造函数
class CalcBody extends React.Component {
constructor(props){
super(props);
this.state = {
calcActive : false,
angleUnits : 'radians',
historyVisible : false,
inverse : false,
prevTotal : '0',
lastInput : '0',
currentMath : [],
exponentCount : 0,
prevMath : '',
rightParensArr : [],
spanStr : '',
calcHistory : [],
inputHistory : [],
inputHistUpdated : true,
newCalc : true
};
【问题讨论】:
-
你能显示更多的代码吗?似乎所有处于状态的对象都在引用内存中的同一个对象,但我没有立即在给定的代码中看到罪魁祸首。
console.log(newinputHist)的输出可能就足够了。 -
抱歉,这里是新手——我如何向您显示该输出?你想看看我的开发工具中有什么吗?
-
不用了,我最感兴趣的是看看
currentMath和rightParensArr的数据类型是什么,但你用新代码给了我。
标签: javascript arrays reactjs