Javascript 我的React Native Expo应用程序中的无限循环在哪里?
在我的应用程序中,我创建了自己的复选框。有两种可用样式:多选或单选。如果该选项位于单个选项上,则一次只能激活一个复选框 当我点击单一类型multi==false的复选框时,应用程序会抛出一个错误 不变冲突:重新渲染过多 我不知道在我的代码中哪里会有一个无限循环 下面是我的代码示例:Javascript 我的React Native Expo应用程序中的无限循环在哪里?,javascript,reactjs,react-native,Javascript,Reactjs,React Native,在我的应用程序中,我创建了自己的复选框。有两种可用样式:多选或单选。如果该选项位于单个选项上,则一次只能激活一个复选框 当我点击单一类型multi==false的复选框时,应用程序会抛出一个错误 不变冲突:重新渲染过多 我不知道在我的代码中哪里会有一个无限循环 下面是我的代码示例: import React, { useState, useEffect } from "react"; import { View, SafeAreaView, Text, ScrollView, StyleShee
import React, { useState, useEffect } from "react";
import { View, SafeAreaView, Text, ScrollView, StyleSheet } from "react-native";
import { generalStyles } from "@gym-app/styles/general";
import { useTranslation } from "react-i18next";
import persistent from "@gym-app/database/persistent";
import CheckboxRow from "../../components/workout/exercises/filters/CheckboxRow";
import tdb from "@gym-app/translation/object";
import Checkbox from "../../components/workout/exercises/filters/Checkbox";
export default function ExercisesFilterScreen() {
const { t } = useTranslation();
const [equipments, setEquipments] = useState({});
const [selectedEquipments, setSelectedEquipments] = useState({});
const [order, setOrder] = useState("");
if (Object.values(equipments).length == 0) {
persistent.transaction(tx => {
tx.executeSql(
"SELECT * FROM equipment",
[],
(t, s) => {
setEquipments(s.rows._array);
},
(t, e) => {
console.log(e);
}
);
});
}
useEffect(() => {
alert(order);
});
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView
style={[
generalStyles.contentContainer,
{ flex: 1, backgroundColor: "#ffb623" }
]}
>
<Text
style={{
fontSize: 30,
fontWeight: "bold",
color: "#ffffff",
textAlign: "center"
}}
>
{t("general.filters").toUpperCase()}
</Text>
<View style={{ marginTop: 10 }}>
<Text style={styles.optionTitle}>
{t("exercise.availableEquipment").toUpperCase()}
</Text>
{Object.values(equipments).map(equipment => {
return (
<CheckboxRow
key={equipment.id}
selected={selectedEquipments}
select={setSelectedEquipments}
multi={true}
id={equipment.id}
>
{tdb(equipment, "name")}
</CheckboxRow>
);
})}
<Text style={styles.optionTitle}>
{t("exercise.order").toUpperCase()}
</Text>
<CheckboxRow
selected={order}
select={setOrder}
multi={false}
id="asc"
>
{t("exercise.easyToHard")}
</CheckboxRow>
<CheckboxRow
selected={order}
select={setOrder}
multi={false}
id="desc"
>
{t("exercise.hardToEasy")}
</CheckboxRow>
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
optionTitle: {
marginBottom: 6,
fontSize: 24,
fontWeight: "bold",
color: "#ffffff",
textAlign: "left"
}
});
以下是CheckboxRow代码:
import React, { useState } from "react";
import { TouchableOpacity, Text, StyleSheet } from "react-native";
import Checkbox from "./Checkbox";
export default function CheckboxRow(props) {
const [checked, setChecked] = useState(false);
if (props.multi == false) {
if (props.selected == props.id) {
setChecked(false);
}
}
return (
<TouchableOpacity
style={styles.row}
onPress={() => {
var id = props.id;
var selected = props.selected;
var s = selected;
if (props.multi == true) {
if (s[id] == undefined) {
s[id] = id;
} else {
delete s[id];
}
} else {
if (s == id) {
s = undefined;
} else {
s = id;
}
}
props.select(s);
console.log(props.select);
setChecked(!checked);
}}
>
<Checkbox checked={checked} />
<Text style={styles.rowText}>{props.children}</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
row: {
flexDirection: "row",
alignItems: "center",
marginBottom: 10
},
rowText: {
fontSize: 26,
color: "white",
marginLeft: 6,
fontWeight: "700"
}
});
不应在呈现范围内调用任何异步方法 我认为这是因为两个原因。sql查询正在每个渲染或复选框更新状态上运行。如果设备为空,请确保sql查询不会反复运行
import React, { useState, useEffect } from "react";
import { View, SafeAreaView, Text, ScrollView, StyleSheet } from "react-native";
import { generalStyles } from "@gym-app/styles/general";
import { useTranslation } from "react-i18next";
import persistent from "@gym-app/database/persistent";
import CheckboxRow from "../../components/workout/exercises/filters/CheckboxRow";
import tdb from "@gym-app/translation/object";
import Checkbox from "../../components/workout/exercises/filters/Checkbox";
export default function ExercisesFilterScreen() {
const { t } = useTranslation();
const [equipments, setEquipments] = useState({});
const [selectedEquipments, setSelectedEquipments] = useState({});
const [order, setOrder] = useState("");
//use useeffect for side effects
useEffect(()=> {
if (Object.values(equipments).length == 0) {
persistent.transaction(tx => {
tx.executeSql(
"SELECT * FROM equipment",
[],
(t, s) => {
setEquipments(s.rows._array);
},
(t, e) => {
console.log(e);
}
);
});
}
},[equipments])
useEffect(() => {
alert(order);
});
return (
<SafeAreaView style={{ flex: 1 }}>
...
</SafeAreaView>
);
}
在复选框组件中,还可以使用useEffect更新状态
export default function CheckboxRow(props) {
const [checked, setChecked] = useState(false);
useEffect(()=>{
if (props.multi == false) {
if (props.selected == props.id) {
setChecked(false);
}
}
},[props.multi, props.selected])
return (
<TouchableOpacity>
...
</TouchableOpacity>
);
}
最后检查依赖项以相应地使用effect钩子