P200p
P200p

Reputation: 29

React Native state not resetting properly on navigating between screens

I am trying to implement the following case with two screens:

  1. Adding players screen
  2. Game screen: Challenges are read from JSON file and filled in with random variables during runtime. Example: in "p(1) drinks sips(2,4)" p(1) will be replaced with a random choice of a list of players, and sips will be replaced by either 2, 3 or 4 sips.

I am using stack navigation, passing the result of adding players in the player screen to the challenge screen. It works perfectly fine when I first start the game, but when I pop screen 2, and go back to screen 2, the challenges appear in random order (as expected), but they are already filled in.

The initialstate reads the non-filled in challenges from a JSON file, so why are the challenges already filled in when I rerender screen 2.

Gamescreen:

import React, { useState } from 'react';
import { StyleSheet, View, Text, TouchableWithoutFeedback, Alert } from 'react-native';
import ChallengeComponent from '../components/gameScreenComponents/challengeComponent'
import { shuffle } from '../helpers/shuffle'
import { fillInSips, fillInChars, fillInNumbers, fillInPlayers, fillInChoice} from '../helpers/challengeRegex'

const GameScreen = ({ route, navigation }) => {
  
  const playersNeeded = (challenge) => {
    return 0 
  }

  const popChallengeHandler = () => {

      if (challenges.length > 1) {
      
      let newChallenges = [...challenges];
      newChallenges.shift()
      processedChallenges = playChallenge(newChallenges)
      setChallenges(processedChallenges)
      }
      else {
        setChallenges([])
      }

  }

  const playChallenge = (currentChallenges) => {

    currentChallenges[0] = fillInChallenge(currentChallenges[0]);
    currentChallenges[0]['nextRounds'].forEach(round => currentChallenges.splice(round[0],0,{
      initialRound: round[1],
      nextRounds: []
    })) 
    return currentChallenges

  }

  const fillInChallenge = (challenge) => {

  return fillInChoice(players)
  
  }

  const endGameHandler = () => {
    Alert.alert("Ending game")
  }
 
  const players = route.params;
  const [challenges, setChallenges] = useState(() => {
    const initialState = playChallenge(shuffle(require('../data/challenges.json').deck.filter(challenge => players.length >= playersNeeded(challenge))));
    return initialState;
  });


  if (challenges.length > 0)
    return (<ChallengeComponent pressHandler={popChallengeHandler} text={challenges[0]['initialRound']} navigation={navigation}/>)
  else
    return (<ChallengeComponent pressHandler={endGameHandler} text="Het spel is afgelopen" navigation={navigation}/>)


}
export default GameScreen;

Navigator:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
 
import AddPlayerScreen from './screens/addPlayers';
import GameScreen from './screens/game';

console.disableYellowBox = true;
 
const RootStack = createStackNavigator();
 
const App = () => {
  return (
    <NavigationContainer>
      <RootStack.Navigator screenOptions={{headerShown: true}}>
        <RootStack.Screen name="AddPlayers" component={AddPlayerScreen} />
        <RootStack.Screen name="Game" component={GameScreen} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
};
 
export default App;

Upvotes: 0

Views: 27

Answers (1)

Ali Ergcr
Ali Ergcr

Reputation: 71

You can use this event listeners to doing some updates or else

navigation.addListener('blur', () => {console.log('focused Out')});


navigation.addListener('focus', () => {console.log('focused')});

Upvotes: 1

Related Questions