Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript (Expo)从服务器获取数据后,响应本机不更新状态_Javascript_Reactjs_React Native_Expo - Fatal编程技术网

Javascript (Expo)从服务器获取数据后,响应本机不更新状态

Javascript (Expo)从服务器获取数据后,响应本机不更新状态,javascript,reactjs,react-native,expo,Javascript,Reactjs,React Native,Expo,我正在用react native创建一个应用程序。我在应用程序中遇到一个问题。我正在从服务器获取数据,并用获取的数据更新我的状态。来自服务器的数据在控制台日志记录中没有任何错误。但是,在设置状态后,react native不会在屏幕上重新呈现我的问题。但当我从代码编辑器中保存项目并重新加载expo时,数据(问题)就会显示在屏幕上。我找不到解决方案,也找不到发生错误的地方。希望下面的代码和gif演示我的问题。 我已经从代码中删除了一些样式以减少长度,但代码仍然很长。可以在此处找到原始文件(代码

我正在用react native创建一个应用程序。我在应用程序中遇到一个问题。我正在从服务器获取数据,并用获取的数据更新我的状态。来自服务器的数据在控制台日志记录中没有任何错误。但是,在设置状态后,react native不会在屏幕上重新呈现我的问题。但当我从代码编辑器中保存项目并重新加载expo时,数据(问题)就会显示在屏幕上。我找不到解决方案,也找不到发生错误的地方。希望下面的代码和gif演示我的问题。

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

import React,{useffect,useState}来自“React”;
从“react native multiple choice picker”导入MultipleChice;
进口{
看法
文本,
(其他进口),
按钮
}从“反应本族语”;
从“./加载”导入加载屏幕;
从“../../config/firebase”导入firebase;
从“../../config/variable”导入服务器;
常量解决方案=({route,navigation})=>{
const[isLoading,setIsLoading]=useState(false);
const[questionData,setQuestionData]=useState([]);
const[correctAnswer,setCorrectAnswer]=useState([]);
常量[ErrorAnswer,SetErrorAnswer]=useState([]);
const[notAttempted,setNotAttempted]=useState([]);
常量[questionCount,setQuestionCount]=useState(0);
const[allQuestion,setAllQuestion]=useState([]);
const{examid}=route.params;
const fetchSolution=async()=>{
设置加载(真);
试一试{
const response=wait fetch(`${SERVER}admin/get/result for user`{
方法:“张贴”,
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
},
正文:JSON.stringify({
电子邮件:firebase.auth().currentUser.email,
examid,
}),
});
const responseData=await response.json();
设置问题数据(应答数据);
setCorrectAnswer(wait JSON.parse(responseData.result[0].correctAnsArr));
const data1=JSON.parse(responseData.result[0].ErrorAnsarr);
设置错误答案(数据1);
setNotAttempted(等待JSON.parse(responseData.result[0].notAttemtedArr));
const datafinal=wait updateQuestion();
设置所有问题(最终数据);
}捕获(错误){
console.log(错误);
警报。警报(“服务器错误”);
}
设置加载(假);
};
常量updateQuestion=()=>{
var correctAnsArr=[];
var=var[];
var notAttemtedArr=[];
for(设i=0;i{
fetchSolution();
}, []);
const RenderQuestion=()=>{
返回(
{allQuestion.length>0(
问题{allQuestion.length}中的问题{questionCount+1}
{allQuestion[questionCount]。isQuestionImage==“1”(
) : (
{allQuestion[questionCount].questionText}
)}
) : (
没有数据
)}
);
};
常量渲染=()=>{
返回(
{allQuestion.length>0(
{allQuestion[questionCount].isOptionImage==“1”(
) : (
)}
) : (
)}
);
};
常量渲染按钮=()=>{
返回(
{问题计数!=0(
{
setQuestionCount(()=>questionCount-1);
}}
/>
):null}
{questionCount+1questionCount+1);
}}
/>
):null}
navigation.navigate(“结果列表”)}
/>
);
};
如果(孤岛加载){
返回;
}
返回(
);
};
导出默认解决方案;
updateQuestion()
函数中,将填充为
allQuestion
的内容,您希望
正确答案、问题数据,
状态保存他们在
fetchSolution()
中获得的数据

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

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



需要明确的是,问题是在第一次渲染时运行
useffect
之后,
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;


  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]);