@hiPaul

Mobx обновление состояния массива в React Native?

В сторе хранится массив объектов с вопросами, пытаюсь добавить к объекту новое свойство с ответом юзера, но mobX ругается на сайд эффект, что я в рэндере меняю состояние массива.

Сам Стор:
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;
    }
  }
}


Ошибка идет при экшне setUserAnswer

Контроллер:
@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>
  );
}


Помогите =)
  • Вопрос задан
  • 267 просмотров
Решения вопроса 1
0xD34F
@0xD34F
ругается на сайд эффект, что я в рэндере меняю состояние массива

Внутри единственного показанного вами render'а есть подозрительный код:

answers={shuffleArray(currentQuestion.answers)}

Наверное, shuffleArray изменяет переданный массив, а не создаёт новый. Ну, попробуйте создавать сами:

answers={shuffleArray([...currentQuestion.answers])}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы