这是我的代码:
import React from "react";
import { View, StyleSheet, StatusBar, Text, SafeAreaView } from "react-native";
import { Button, ButtonContainer } from "../components/Button";
import { Alert } from "../components/Alert";
import firebase from "../config/firebase";
import "firebase/firestore";
const styles = StyleSheet.create({
container: {
backgroundColor: "red",
flex: 1,
paddingHorizontal: 20
},
text: {
color: "#fff",
fontSize: 25,
textAlign: "center",
letterSpacing: -0.02,
fontWeight: "600"
},
safearea: {
flex: 1,
marginTop: 100,
justifyContent: "space-between"
}
});
class Quiz extends React.Component {
state = {
correctCount: 0,
totalCount: 0,
activeQuestionIndex: 0,
answered: false,
answerCorrect: false,
questions: []
};
async componentDidMount() {
await this.questions();
}
questions = async () => {
const documents = await firebase
.firestore()
.collection("questions")
.where("quizId", "==", this.props.navigation.getParam("uid"))
.get();
const questions = documents.docs.map(doc => {
return { uid: doc.id, ...doc.data() };
});
return this.setState({ questions });
};
answer = correct => {
this.setState(
state => {
const nextState = { answered: true };
if (correct) {
nextState.correctCount = state.correctCount + 1;
nextState.answerCorrect = true;
} else {
nextState.answerCorrect = false;
}
return nextState;
},
() => {
setTimeout(() => this.nextQuestion(), 750);
}
);
};
nextQuestion = () => {
this.setState(state => {
const nextIndex = state.activeQuestionIndex + 1;
if (nextIndex >= state.totalCount) {
return this.props.navigation.navigate("Result", {
correct: this.state.correctCount
});
}
return {
activeQuestionIndex: nextIndex,
answered: false
};
});
};
render() {
console.log(this.state.questions);
const questions = this.props.navigation.getParam("questions", []);
const question = questions[this.state.activeQuestionIndex];
return (
<View
style={[
styles.container,
{ backgroundColor: this.props.navigation.getParam("color") }
]}
>
<StatusBar barStyle="light-content" />
<SafeAreaView style={styles.safearea}>
<View>
<Text style={styles.text}>
{this.state.activeQuestionIndex + 1}.{question.question}
</Text>
<ButtonContainer>
{question.answers.map(answer => (
<Button
key={answer.id}
text={answer.text}
onPress={() => this.answer(answer.correct)}
/>
))}
</ButtonContainer>
</View>
{/* <Text style={styles.text}>
{`${this.state.correctCount}/${this.state.totalCount}`}
</Text> */}
</SafeAreaView>
{/* <Alert
correct={this.state.answerCorrect}
visible={this.state.answered}
/> */}
</View>
);
}
}
export default Quiz;
console.log
被触发两次。第一次返回空数组,第二次返回期望的元素。据我了解,由于async
上的componentDidMount
的存在,第二次渲染是因为questions
方法的状态发生了变化。我明白吗?我的问题是如何防止这种情况发生?因为这种方式会因为下面的代码中断而在第一个渲染器上引发错误。谢谢!
答案 0 :(得分:1)
您的问题将在安装后异步加载。
我建议将您的初始questions
更改为undefined
,例如
state = {
...
questions: undefined
};
并在渲染中进行检查。如果questions
未定义,则仍在加载内容。
render() {
if(this.state.questions === undefined) return null;
// ...