Answer the question
In order to leave comments, you need to log in
Mobx array state update in React Native?
The store stores an array of objects with questions, I'm trying to add a new property to the object with the user's answer, but mobX swears at the side effect that I change the state of the array in the renderer.
Stour himself:
class TestStore {
@observable questionsArray;
@observable currentQuestionIndex;
constructor() {
this.questionsArray = stub;
this.currentQuestionIndex = 0;
}
@computed get questionsArrayLength() {
return this.questionsArray.length;
}
@computed get currentQuestion() {
return this.questionsArray[this.currentQuestionIndex];
}
@action setUserAnswer = answer => {
this.questionsArray[this.currentQuestionIndex] = {
...this.currentQuestion,
userAnswer: answer
};
}
@action setCurrentQuestionIndex = index => {
if (index > 0 && index < this.questionsArray.length) {
this.currentQuestionIndex = index;
}
}
}
@inject("testStore")
@observer
export default class QuestionsScreen extends React.Component {
handleFirstPress = (answer) => {
const {
testStore: { setUserAnswer }
} = this.props;
setUserAnswer(answer);
};
handleSecondPress = () => {
const {
testStore: {
currentQuestionIndex,
setCurrentQuestionIndex,
currentQuestion: { userAnswer }
}
} = this.props;
if (!userAnswer) {
return;
}
setCurrentQuestionIndex(currentQuestionIndex + 1);
};
render() {
const {
testStore: {
currentQuestion,
currentQuestionIndex,
questionsArrayLength,
// setUserAnswer
}
} = this.props;
return (
<TouchableWithoutFeedback onPress={this.handleSecondPress}>
<View style={styles.container}>
<View style={{ width: "100%" }}>
<Text>{`Вопрос №${currentQuestionIndex + 1}`}</Text>
<HorisontalList
values={this.getButtonsList(questionsArrayLength)}
/>
<QuestionsWithAnswers
question={currentQuestion.question}
answers={shuffleArray(currentQuestion.answers)}
right={currentQuestion.right}
userAnswer={currentQuestion.userAnswer}
onFirstPress={this.handleFirstPress}
onSecondPress={this.handleSecondPress}
/>
</View>
<TouchableOpacity style={styles.describeButton}>
<Text style={styles.buttonText}>Обсуждение вопроса</Text>
<Text style={styles.buttonSubText}>3 комментария</Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
);
}
}
export default function QuestionsWithAnswers({
answers = [],
right,
question,
isExam,
onFirstPress,
onSecondPress,
userAnswer
}) {
const [isFavorite, setFavorite] = useState(false);
const handlePressButton = (selectedItem) => {
if (isExam) {
// логика при экзамене
} else {
// логика при тренировке
if (!userAnswer) {
onFirstPress(selectedItem);
} else {
onSecondPress();
}
}
}
return (
<View style={styles.container}>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
width: "90%" //moment so interesting
}}
>
<Text style={styles.text}>{question}</Text>
<Text style={{ fontSize: 40 }} onPress={() => setFavorite(!isFavorite)}>
{isFavorite ? "★" : "☆"}
</Text>
</View>
{answers.map((el, index) => (
<TouchableOpacity
key={index}
onPress={() => handlePressButton(el)}
style={[
styles.listItem,
{ backgroundColor: getAnswerBackgroundColor(el) }
]}
>
<Text>{el}</Text>
</TouchableOpacity>
))}
</View>
);
}
Answer the question
In order to leave comments, you need to log in
swears at the side effect that I change the state of the array in the renderer
answers={shuffleArray([...currentQuestion.answers])}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question