skip to Main Content

I am new to React Native and I am trying to set the property of pollQuestion from QuestionGroup.js and passing it into the next page, PollDetailsScreen after clicking on the right header button, Send. How would I go about doing this with react-navigation?

Here’s a visualisation of what I am trying to achieve:
App demo

App.js

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Button } from 'react-native';
import { PollScreen } from './components/PollScreen';
import { PollDetailsScreen } from './components/PollDetailsScreen';
import { AppTheme } from './styles/Theme';
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { MainScreen } from "./components/MainScreen";

const Stack = createNativeStackNavigator()

function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <SafeAreaProvider>
        <NavigationContainer theme={AppTheme}>
          <Stack.Navigator initialRouteName="Main">
            ...
            <Stack.Screen name="NewPoll" component={PollScreen} options={({ navigation }) => ({
              title: 'New Poll',
              headerLeft: () => (
                <Button onPress={() => navigation.navigate('Main')}
                  title="Cancel"
                  color="#617A67" />
              ),
              headerRight: () => (
                <Button onPress={() =>
                  navigation.navigate('Poll', {
                    pollQuestion: 'This is a question',
                    pollOptions: []
                  })
                }
                  title="Send"
                  color='#617A67'
                />
              )
            })} />
            <Stack.Screen name="Poll" component={PollDetailsScreen} options={({ navigation }) => ({
              title: 'Poll',
              headerLeft: () => (
                <Button onPress={() => navigation.navigate('NewPoll')} title="Close" color='#617A67' />
              )
            })} />
          </Stack.Navigator>
        </NavigationContainer>
      </SafeAreaProvider>
    </GestureHandlerRootView>
  );
}

export default App;

PollScreen.js

import { View } from "react-native"
import { OptionsGroup } from "./OptionsGroup"
import { MultipleAnswersSwitch } from "./MultipleAnswers"
import { QuestionGroup } from "./QuestionGroup"

export function PollScreen() {
    return (
        <View style={{ margin: 24 }}>
            <QuestionGroup />
            <OptionsGroup />
            <MultipleAnswersSwitch />
        </View>
    )
}

QuestionGroup.js

import { StyleSheet, Text, TextInput, View } from "react-native";
import { useState } from "react"

export function QuestionGroup() {
    const [charCount, setCharCount] = useState("")

    return (
        <>
            <View>
                <Text>Question</Text>
                ...
            <TextInput style={inputBoxStyle.input} placeholder="Ask a question" multiline={true} onChangeText={value => {
                setCharCount(value)
            }} />
        </>
    )
}

const inputBoxStyle = StyleSheet.create({
    ...
})

PollDetailsScreen.js

import { useState } from "react";
import { FlatList, SafeAreaView, StatusBar, StyleSheet, Text, TouchableOpacity, View } from "react-native";
...

export function PollDetailsScreen({ navigation, route }) {
    const { pollQuestion, pollOptions } = route.params;
    ...


    return (
        <View>
            <Text>{pollQuestion}</Text>
            ...
        </View>
    )
}

const styles = StyleSheet.create({
    ...
});

2

Answers


  1. You need to update the pollScreen component to manage the state of the question and then pass it as a parameter when navigating.

    first things first update QuestionGroup.js to lift the state up to PollScreen.js by using a callback function. This way, PollScreen can keep track of the pollQuestion state and pass it to the PollDetailsScreen.

    then in QuestionGroup.js, accept a prop for setting the question and call it when the text input changes:

    export function QuestionGroup({ onQuestionChange }) {
        const [charCount, setCharCount] = useState("");
    
        return (
            <>
                <View>
                    <Text>Question</Text>
                    ...
                    <TextInput
                        style={inputBoxStyle.input}
                        placeholder="Ask a question"
                        multiline={true}
                        onChangeText={value => {
                            setCharCount(value);
                            onQuestionChange(value); // Call the callback function with the new value
                        }}
                    />
                </View>
            </>
        );
    }
    

    inPollScreen.js, manage the state for pollQuestion and pass it to QuestionGroup:

    export function PollScreen({ navigation }) {
        const [pollQuestion, setPollQuestion] = useState("");
    
        return (
            <View style={{ margin: 24 }}>
                <QuestionGroup onQuestionChange={setPollQuestion} />
                <OptionsGroup />
                <MultipleAnswersSwitch />
                {/* Rest of your component */}
            </View>
        );
    }
    

    Modify the headerRight button in App.js inside the PollScreen stack screen to use the pollQuestion state when navigating to PollDetailsScreen:

    <Stack.Screen
        name="NewPoll"
        component={PollScreen}
        options={({ navigation }) => ({
            title: 'New Poll',
            // Other options...
            headerRight: () => (
                <Button
                    onPress={() => navigation.navigate('Poll', {
                        pollQuestion: pollQuestion, // Use the state value
                        pollOptions: [] // And any other data you need to pass
                    })}
                    title="Send"
                    color="#617A67"
                />
            )
        })}
    />
    

    you still need to get the pollQuestion state from PollScreen component and pass it to the options prop function. This means either lifting the state up further (to App.js) and managing it there, or using a state management library

    Login or Signup to reply.
  2. Move header button interaction to its screen component using setOptions for full control of parameters. Something like this:

    function PollScreen({ navigation }) {
    ...
      React.useEffect(() => {
        navigation.setOptions({
          headerRight: () => (
            <Button onPress={() => /* TODO */ } title="Send" />
          ),
        });
      }, [navigation]);
    ...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search