EDIT: For those stumbling on this, disregard this question. It was a simple mistake on my end. React hook variable sharing between screen components works fine.
I have my App.js
file as follows
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Main from './src/Main';
import Game from './src/Game';
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Main" component={Main} />
<Stack.Screen name="Game" component={Game} />
</Stack.Navigator>
</NavigationContainer>
)
}
Main.js
(relevant parts)
export default function Main({ navigation }) {
const [username, setUsername] = useState(null);
...
<TextInput
mode='outlined'
label='Enter username here'
onChangeText={text => setUsername(text)}
/>
<Button
mode='contained'
onPress={() =>
navigation.navigate('Game', {'username': username})
}
>
Create
</Button>
...
Game.js
(relevant parts)
export default function Game({ navigation, route }) {
return (
<View>
<Text>
{route.params.username}
</Text>
</View>
);
}
How do I pass in my username
state variable using React hooks from my Main
component to my Game
component? Currently I'm getting the following error on the {route.params.username}
line in Game.js
:
Objects are not valid as a React child (found: object with keys {replace, push, pop, popToTop, goBack, navigate, reset, setParams, dispatch, isFocused, canGoBack, dangerouslyGetParent, dangerouslyGetState, addListener, removeListener, setOptions}).
I just want to pass in whatever the most recent string value of username
is after the button in Main
screen is clicked (which should navigate away to Game
screen), but it seems like the passed in value is an object.
The code you posted in the question works fine, but I think I found the problem(s) from looking at your snack.
The first thing is that your utils.createGame
function expects one parameter username
, but you pass navigation
to it and username
like this:
onPress={() =>
utils.createGame(navigation, username).then(payload => {
navigation.navigate("Game", payload);
})
}
So remove navigation
as a parameter instead:
onPress={() =>
utils.createGame(username).then(payload => {
navigation.navigate("Game", payload);
})
}
The same thing goes for utils.addPlayer
where the function takes two parameters, but you pass three.
To give more context, but to also fix another problem, change how you define utils
to this:
const utils = {
createGame: async function(username) {
const gameId = cryptorandomstring({ length: 6, type: 'distinguishable' });
const playerId = cryptorandomstring({ length: 10 });
return { 'gameId': gameId, 'creatorId': playerId, 'username': username };
},
addPlayer: async function(username, gameId) {
const playerId = cryptorandomstring({ length: 10 });
return { 'gameId': gameId, 'playerId': playerId, 'username': username };
}
}
Inside addPlayer
you had a return statement like this:
return { 'gameId': gameId, 'playerId': playerId, 'playerUserName': username };
The problem with this as that inside Game.js
you're destructuring username
from the params and not playerUserName
. So the destructured username
variable won't hold the correct value.