React Native:太多的重新渲染.React 限制渲染的数量以防止无限循环



我刚刚在YouTube上完成了React Native的待办事项列表教程,我决定尝试向其添加一些功能,例如确认模式。问题是每当我尝试将任何内容传递到模态"完成任务"时,我都会收到此错误:

错误:重新渲染过多。React 限制渲染的数量以防止无限循环。

import React, { useState } from "react";
import {
KeyboardAvoidingView,
Platform,
StyleSheet,
Text,
TextInput,
Keyboard,
TouchableOpacity,
View,
} from "react-native";
import Modal from "react-native-modal";
import Task from "./components/Task";
export default function App() {
const [task, setTask] = useState();
const [taskItems, setTaskItems] = useState([]);
const [modalVisable, setModalVisable] = useState(false);
const [itemToDelete, setItemToDelete] = useState();
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task]);
setTask(null);
};
const completeTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice(index, 1);
setTaskItems(itemsCopy);
};
const closeModal = (itemToDelete) => {
completeTask(itemToDelete)
setModalVisable(false);
};
const handleRemoveTask = (index) => {
setModalVisable(true);
};

return (
<View style={styles.container}>
<View style={styles.tasksWrapper}>
<Text style={styles.sectionTitle}>Your Tasks</Text>
<View style={styles.items}>
{taskItems.map((item, index) => {
return (
<TouchableOpacity
key={index}
onPress={() => {
handleRemoveTask(index);

}}
>
<Task text={item} />
</TouchableOpacity>
);
})}
</View>
</View>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.writeTaskWrapper}
>
<TextInput
style={styles.input}
placeholder={"Add a task!"}
value={task}
onChangeText={(text) => setTask(text)}
/>
<TouchableOpacity onPress={() => handleAddTask()}>
<View style={styles.addWrapped}>
<Text style={styles.addText}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
<View style={styles.modalWrapper}>
<Modal
style={styles.modal}
isVisible={modalVisable}
onBackdropPress={closeModal}
>
<Text style={styles.modalText}>Test Modal</Text>
<TouchableOpacity style={styles.closeButton} onPress={closeModal(itemToDelete)}>
<Text style={styles.modalText}>
Complete Task
</Text>
</TouchableOpacity>
</Modal>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#E8EAED",
},
tasksWrapper: {
paddingTop: 80,
paddingHorizontal: 20,
},
sectionTitle: {
fontSize: 24,
fontWeight: "bold",
},
items: {
marginTop: 30,
},
writeTaskWrapper: {
position: "absolute",
bottom: 50,
width: "100%",
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
},
input: {
paddingVertical: 15,
paddingHorizontal: 15,
backgroundColor: "#FFF",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
textAlign: "center",
width: 300,
},
addWrapped: {
width: 60,
height: 60,
backgroundColor: "#FFF",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
justifyContent: "center",
alignItems: "center",
},
addText: {},
modalWrapper: {},
modal: {
backgroundColor: "#FFF",
maxHeight: 250,
},
modalText: {
fontWeight: "bold",
textAlign: "center",
justifyContent: "center",
},
closeButton: {
justifyContent: "center",
position: "absolute",
width: "100%",
height: 30,
bottom: 0,
backgroundColor: "#BE33FF",
},
});

我已经尽力尝试一些我能想到的解决方法,但唉,我找不到方法。如果你有任何想法,我会感谢你的帮助,谢谢Lachie。

这行对我来说很可疑

onPress={closeModal(itemToDelete)}

您将在每个渲染上调用closeModal函数。

onPress 期望在按下任何内容时调用函数。 您应该将其替换为

onPress={function() { closeModal(itemToDelete);}

或速记版本

onPress={() => { closeModal(itemToDelete) }

你的错误就在这里:

<TouchableOpacity style={styles.closeButton} onPress={closeModal(itemToDelete)}>

渲染后立即调用的closeModal(itemToDelete)道具,它本身就是调用completeTask(itemToDelete),然后调用setTaskItems(itemsCopy)。 最后一个函数会导致无限渲染周期。

您可能希望的是,在用户单击TouchableOpacity后调用closeModal(itemToDelete),如下所示:

<TouchableOpacity style={styles.closeButton} onPress={() => closeModal(itemToDelete)}>

最新更新