reactjs - React Hooks reducer 导致内存泄漏
问题描述
我有一个 React 组件,它在初始化时调用 reducer 来填充一个数组,其中包含与 firebase db 中指定的数字一样多的空白记录。如果 firebase db 字段 myArray 长度为 5,则组件将初始化并调用 reducer 在上下文中的数组中创建 5 条空白记录:
import React, { useState, useEffect, useContext } from 'react';
import { useHistory, useLocation } from 'react-router';
import ArrayCard from '../../../containers/ArrayCard';
import firebase from '../../../Utils/firebase';
import MyContext from '../../../Utils/contexts/MyContext ';
import { initialiseMyArray, changeArray} from '../../../Utils/reducers/MyActions';
function MyComponent() {
const { push } = useHistory();
const location = useLocation();
const context = useContext(MyContext);
const dispatch = context.dispatch;
const session = location.state.currentSession;
const sessionRef = firebase.firestore().collection("sessions").doc(session);
const [ loaded, setLoaded ] = useState(false);
const [ myArray, setMyArray] = useState([]);
const [ myArrayCurrentIndex, setMyArrayCurrentIndex ] = useState();
const getSessionData = () => {
sessionRef.get().then(function(doc) {
if (doc.exists) {
const myArrayLength= parseInt(doc.data().myArrayLength);
dispatch({ type: initialisePensionsFromFirebase, myArrayLength: myArrayLength});
setMyArrayCurrentIndex (0);
setLoaded(true);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
}
useEffect(() => {
if (sessionRef && !loaded && myArray.length < 1) {
getSessionData();
}
if (context) {
console.log("CONTEXT ON PAGE: ", context)
}
}, [loaded, currentIndex])
上下文中新创建的 myArray 的索引 currentIndex 用于填充此组件内的组件:
return (
<innerComponent
handleAmendSomeproperty={(itemIndex, field, value) => handleAmendSomeproperty(itemIndex, field, value)}
itemIndex={currentIndex}
someproperty={context.state.someitem[currentIndex].someproperty}
></innerComponent>
)
我希望能够修改 myArray[currentIndex] 中的 someproperty 字段,但我的调度会导致无休止的重新渲染。
const handleAmendSomeproperty= (itemIndex, field, value) => {
dispatch({ type: changeItem, itemIndex: itemIndex});
}
我的减速机开关盒是这样的:
case initialiseMyArray:
console.log("SRSTATE: ", state);
let _initialArray = []
for (let i=0; i<action.myArrayLength; i++) {
_initialArray .push(
{
itemIndex: i,
someproperty: "" }
)
}
return {
...state,
someproperty: [..._initialArray ]
};
case changeArray:
// I want to leave the state untouched at this stage until I stop infinite rerenders
return {
...state
};
发生了什么导致无限重新渲染?为什么我不能修改一些属性,但是在状态下初始化新数组可以正常工作?
innerComponent 有很多这样的版本:
<div>
<label>{label}</label>
<div onClick={() => handleAmendSomeproperty(itemIndex, "fieldName", "fieldValue")}>
{someproperty === "booleanValue" ? filled : empty}
</div>
</div>
和很多这样的:
<input
type="text"
placeholder=""
value={somepropertyvalue}
onChange={(event) => handleAmendSomeproperty(itemIndex, "fieldName", event.target.value)}
/>
解决方案
推荐阅读
- java - 如何弄清楚 model.getName() 指向 Firebase 中的内容
- php - 如果 index.php 不在 URL 中,则在所需文件中使用 URI 嵌入图像的服务器错误
- java - 查找字符串中的模式计数(包括重叠)
- xamarin.ios - Xamarin IOS 构建错误 MSB4184:无法评估表达式“[System.IO.Path]::GetDirectoryName('')”
- react-native - 导航回我的原始组件时不会再次调用 componentWillMount
- java - hashmap 和数组在查找时间复杂度上的区别
- javascript - 如何在另一个中创建反应元素?
- python - 什么是 Tensorflow qint8、quint8、qint32、qint16 和 quint16 数据类型?
- mingw - 32 位 MSYS2 上的 p11tool 无法加载
- python - 在 DataFrame 中,我们如何获取特定列中包含 0 的索引列表?