gpt4 book ai didi

javascript - (博览会)React Native 从服务器获取数据后不更新状态

转载 作者:行者123 更新时间:2023-12-02 20:58:08 24 4
gpt4 key购买 nike

我正在用react-native创建一个应用程序。我在应用程序中遇到问题。我正在从服务器获取数据并使用获取的数据更新我的状态。来自服务器的数据是控制台记录,没有任何错误。然而,在设置状态后,react-native 不会在屏幕上重新呈现我的问题。但是当我从代码编辑器保存我的项目并重新加载博览会时,数据(问题)在屏幕上可见。我找不到解决方案或从哪里发生错误。希望下面的代码和 gif 能说明我的问题。

我已经从代码中删除了一些样式以减少长度,但代码仍然很长。原始文件(代码)的链接可以在这里找到 link to code

Error Image

import React, { useEffect, useState } from "react";
import MultipleChoice from "react-native-multiple-choice-picker";
import {
View,
Text,
(other imports),
Button,
} from "react-native";
import LoadingScreen from "../Loading";
import firebase from "../../config/firebase";
import SERVER from "../../config/variable";

const Solution = ({ route, navigation }) => {
const [isLoading, setIsLoading] = useState(false);
const [questionData, setQuestionData] = useState([]);
const [correctAnswer, setCorrectAnswer] = useState([]);
const [wrongAnswer, setWrongAnswer] = useState([]);
const [notAttempted, setNotAttempted] = useState([]);
const [questionCount, setQuestionCount] = useState(0);
const [allQuestion, setAllQuestion] = useState([]);
const { examid } = route.params;

const fetchSolution = async () => {
setIsLoading(true);
try {
const response = await fetch(`${SERVER}admin/get/result-for-user`, {
method: "POST",
headers: {
Accept: "Application/json",
"Content-Type": "Application/json",
},
body: JSON.stringify({
email: firebase.auth().currentUser.email,
examid,
}),
});
const responseData = await response.json();
setQuestionData(responseData.data);
setCorrectAnswer(await JSON.parse(responseData.result[0].correctAnsArr));
const data1 = JSON.parse(responseData.result[0].wrongAnsArr);
setWrongAnswer(data1);
setNotAttempted(await JSON.parse(responseData.result[0].notAttemtedArr));
const datafinal = await updateQuestion();
setAllQuestion(datafinal);
} catch (error) {
console.log(error);
Alert.alert("Server Error");
}
setIsLoading(false);
};

const updateQuestion = () => {
var correctAnsArr = [];
var wrongAnsArr = [];
var notAttemtedArr = [];

for (let i = 0; i < correctAnswer.length; i++) {
for (let j = 0; j < questionData.length; j++) {
if (correctAnswer[i].questionId === questionData[j].id) {
questionData[j].selectedOption = correctAnswer[i].selectedOption;
correctAnsArr.push(questionData[j]);
}
}
}

for (let i = 0; i < wrongAnswer.length; i++) {
for (let j = 0; j < questionData.length; j++) {
if (wrongAnswer[i].questionId === questionData[j].id) {
questionData[j].selectedOption = wrongAnswer[i].selectedOption;
wrongAnsArr.push(questionData[j]);
}
}
}

for (let i = 0; i < notAttempted.length; i++) {
for (let j = 0; j < questionData.length; j++) {
if (notAttempted[i].questionId === questionData[j].id) {
questionData[j].selectedOption = notAttempted[i].selectedOption;
notAttemtedArr.push(questionData[j]);
}
}
}

return [...correctAnsArr, ...wrongAnsArr, ...notAttemtedArr];
};

useEffect(() => {
fetchSolution();
}, []);

const RenderQuestion = () => {
return (
<View>
<View>
{allQuestion.length > 0 ? (
<View
key={allQuestion[0].id}
style={{
width: Dimensions.get("window").width,
}}
>
<View style={{ margin: 10 }}>
<Text style={{ fontSize: 16 }}>
Question {questionCount + 1} of {allQuestion.length}
</Text>
</View>

{allQuestion[questionCount].isQuestionImage === "1" ? (
<View
style={{
width: Dimensions.get("window").width,
display: "flex",
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Image
style={{
height: Dimensions.get("window").height * 0.5,
width: Dimensions.get("window").width * 0.8,
}}
source={{
uri: allQuestion[questionCount].questionFile,
}}
/>
</View>
) : (
<View>
<Text style={{ fontSize: 35, margin: 15 }}>
{allQuestion[questionCount].questionText}
</Text>
</View>
)}
<RenderOption />
</View>
) : (
<View>
<Text>No Data</Text>
</View>
)}
</View>
</View>
);
};

const RenderOption = () => {
return (
<View>
{allQuestion.length > 0 ? (
<View>
{allQuestion[questionCount].isOptionImage === "1" ? (
<MultipleChoice
direction={"column"}
chosenIndex={allQuestion[questionCount].selectedOption}
choices={[
<Image
style={{
height: Dimensions.get("window").height * 0.3,
width: Dimensions.get("window").width * 0.6,
}}
source={{
uri: allQuestion[questionCount].optionAFile,
}}
/>,
<Image
style={{
height: Dimensions.get("window").height * 0.3,
width: Dimensions.get("window").width * 0.6,
}}
source={{
uri: allQuestion[questionCount].optionBFile,
}}
/>,

<Image
style={{
height: Dimensions.get("window").height * 0.3,
width: Dimensions.get("window").width * 0.6,
}}
source={{
uri: allQuestion[questionCount].optionCFile,
}}
/>,
<Image
style={{
height: Dimensions.get("window").height * 0.3,
width: Dimensions.get("window").width * 0.6,
}}
source={{
uri: allQuestion[questionCount].optionDFile,
}}
/>,
]}
/>
) : (
<MultipleChoice
direction={"column"}
chosenIndex={allQuestion[questionCount].selectedOption}
choices={[
<Text>
{allQuestion[questionCount].optionAText}
</Text>,
<Text>
{allQuestion[questionCount].optionBText}
</Text>,
<Text>
{allQuestion[questionCount].optionCText}
</Text>,
<Text>
{allQuestion[questionCount].optionDText}
</Text>,
]}
/>
)}
</View>
) : (
<View></View>
)}
</View>
);
};
const Renderbutton = () => {
return (
<View>
{questionCount != 0 ? (
<View>
<Button
color="#f9a602"
title="Prev"
onPress={() => {
setQuestionCount(() => questionCount - 1);
}}
/>
</View>
) : null}
{questionCount + 1 < allQuestion.length ? (
<View>
<Button
title="Next"
onPress={() => {
setQuestionCount(() => questionCount + 1);
}}
/>
</View>
) : null}

<View>
<Button
color="red"
title="Finish"
onPress={() => navigation.navigate("ResultList")}
/>
</View>
</View>
);
};

if (isLoading) {
return <LoadingScreen />;
}
return (
<SafeAreaView style={{ display: "flex", flex: 1 }}>
<ImageBackground
source={require("../../images/signup_screen.jpg")}
style={{ flex: 1, resizeMode: "cover" }}
>
<View>
<ScrollView>
<RenderQuestion />
<Renderbutton />
</ScrollView>
</View>
</ImageBackground>
</SafeAreaView>
);
};

export default Solution;


最佳答案

updateQuestion() 函数中,将填充为 allQuestion 的内容,您期望 CorrectAnswer、questionData、... 状态保持不变他们在 fetchSolution() 中获取的数据。

问题是,setState 函数是异步调用,当您进入 updateQuestion() 时,从 fetchSolution() 内部,状态并不是您所期望的那样。

添加一个示例,说明如何使用 useEffect 等待更改影响状态,然后才会触发操作

<小时/>
  const Solution = ({ route, navigation }) => {
const [questionData, setQuestionData] = useState([]);
const [correctAnswer, setCorrectAnswer] = useState([]);
const [allQuestion, setAllQuestion] = useState([]);

const fetchSolution = async () => {
setQuestionData(['something'])
setCorrectAnswer(['something'])
}

useEffect(() => fetchSolution(), []);
useEffect(() => correctAnswer.length && questionData.length &&
updateQuestion(), [correctAnswer, questionData]);

关于javascript - (博览会)React Native 从服务器获取数据后不更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61424484/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com