我开始使用React(仅适用于钩子),并且面临一个奇怪的问题。我正在尝试通过一个小的测试代码重现该问题,但是除了在功能完善的应用程序中,它无法实现。这使我想知道我是否做错了什么。
我有一个对象数组,声明为状态。我映射此数组以显示其内容。除了什么都没有显示(数组已填充,但什么都没有显示)。现在,如果我声明一个不相关的状态,则将其设置为一个布尔值,该值在每次更新数组时都会翻转,然后正确显示我的数组。好像在渲染阶段本身,React并未检测到阵列的更改。
几件事:
本质上,这就是我在做什么:
const updateArray = (setTestArray, setTestTag, addArray) => {
setTestArray(prevTestArray => {
let newTestArray = prevTestArray.map((data, index) => (data + addArray[index]))
return newTestArray
})
setTestTag(prevTag => {
return (!prevTag)
})
}
const renderArray = (currentTestArray) => {
return currentTestArray.map((data, index) => (
<div>
testArray[{index}]={data}
</div>
))
}
function TestPage(props) {
const [testArray, setTestArray] = useState([])
const [testTag, setTestTag] = useState(false)
useEffect(() => {
let samples = 3
let initArray= []
for (let i=0; i<samples;i++) initArray[i] = Math.random()
setTestArray(initArray)
// In real code: setup socket here...
setInterval(() => {
let addArray= []
for (let i=0; i<samples;i++) addArray[i] = Math.random()
updateArray(setTestArray, setTestTag, addArray)
}, 1000)
return (() => {
// In real code, disconnect socket here...
})
}, []);
return (
<Paper>
Array content:
{renderArray(testArray)}
<br/>
Tag: {(testTag)? 'true' : 'false'}
</Paper>
)
}
这很好用。但是,在我完整的应用程序中,如果我注释掉所有与“ testTag”有关的内容,那么我的数组内容将永远不会显示。 testArray的内容符合预期,可以很好地更新,但是将调试器放置在map部分中会显示该数组为空。
因此我的问题:
作为一个副要说明,我的数组的内容实际上是真正的应用程序(对象数组)更复杂,我尝试将其放置在此测试代码中,它也可以正常工作...
谢谢!
编辑:请注意,在useEffect中移动updateArray似乎是推荐的模式。我在完整的应用程序中做到了这一点。钩子linter不会抱怨缺少任何依赖项,但这在我的完整应用程序中仍然无法正常工作。
但是问题仍然是我在这里做的事是否错:我知道这违反了指导方针,因为它阻止了短绒棉衫的工作,但是在我看来,这仍然会起作用,以前的状态可以在设置器功能中默认访问。
编辑#2:对我感到羞耻……我的真实应用程序代码中存在一个愚蠢的错误,等效于updateArray在某个位置具有浅数组副本,而不是深副本。 为什么要添加翻转标签使其起作用,这超出了我的范围(知道确实可以正确显示和更新数据),但是摆脱此错误就可以解决所有问题。
我将继续讨论这个问题,因为问题仍然存在:将状态更新和部分呈现置于组件外部是一个功能性问题,或者只是可能依赖于隐藏依赖项的某些问题(防止react hooks linter做它的工作),因此仅仅是不好的做法?
事实是,组件函数之外的两个函数现在都可以正常工作,这基于我从钩子上了解的内容。