Oussama Nm
Oussama Nm

Reputation: 83

How to update props of a Tab.Screen from Parent Component (passing a state value) , react native

My project Config :

{
   "expo" : "^45.0.0",
   "react-native": "0.68.2",
   "@react-navigation/bottom-tabs": "^6.0.9",
   "@react-navigation/drawer": "^6.1.8",
   "@react-navigation/material-top-tabs": "^6.0.6",
   "@react-navigation/native": "^6.0.6",
}

i'm using TopTabNavigator , to create four screens

const [dataStep1, setDataStep1] = useState({});
const [dataStep2, setDataStep2] = useState({});
const [dataStep3, setDataStep3] = useState({});

const step1Order = (dataInputs) =>
{
    if (dataInputs == null || dataInputs == {})
    {
        Alert.alert("Unknown Error", "Order Not Created , Please Check inputs you Entred");
        return;
    }

    setDataStep1(dataInputs);
}

// same above function for step2 & step3 step2Order() step3Order()


return (

<NavigationContainer>
   <Tab.Navigator>
       <Tab.Screen name="Step 1" component={Step1} initialParams={{ hundlerFillData: step1Order,}}/>
       <Tab.Screen name="Step 2" component={Step2} initialParams={{hundlerFillData: step2Order}} />
       <Tab.Screen name="Step 3" component={Step3} initialParams={{hundlerFillData: step3Order}} />
       <Tab.Screen name="Step 4" component={Step4} 
             initialParams={{
                  confirmOrder: step4Order,
                  dataOrder : {
                      dataStep1: dataStep1,
                      dataStep2: dataStep2,
                      dataStep3: dataStep3,
                  },
             }}
       />

    </Tab.Navigator>
</NavigationContainer> 

--> in the First 3 Steps (screens) i'm fill states using Callback functions "step#Order"

What i want is when i fill data in steps 1,2,3 i want the props of 'Screen 4' to be update automaticlly , i used states on initialParams, but it the screen component does not re-rendred

const Step4 = ({route, navigation}, props ) => {

    const {confirmOrder, dataOrder} = route?.params;

    useEffect(()=> {
        console.log("Step 4 Loaded ====  with dataOrder : \n", dataOrder);
    },[])

    /// Screen Focus
    useEffect(()=> {

        const unsubscribe = navigation.addListener('focus', () => {
            console.log("\n---- mini Hello in Focus Step 4 ----\n with props : \n", route.params);
        });
    
        return unsubscribe;
    }, [route]);


    return (
        <.../>
    )
}

Upvotes: 0

Views: 1678

Answers (1)

Abe
Abe

Reputation: 5508

The most commonly used way to do what you're describing is to use navigation params in the navigate call. So, if you have all the data you need in screen 3, you'd call something like

navigation.navigate('Screen4', { dataStep1, dataStep2, dataStep3 });

And then in screen 4, since you're using hooks:

const { params } = useRoute();
const { dataStep1, dataStep2, dataStep3 } = params || {};

Also, assuming you don't need the data anywhere else, you don't have to keep the state at the navigator level and pass callbacks to each screen. You can just use navigation params as above to pass the data from one screen to the next.

// screen 1
navigation.navigate('Screen2', { dataStep1 });

// screen 2
const { params } = useRoute();
const { dataStep1 } = params || {};
...
navigation.navigate('Screen3', { dataStep1, dataStep2 });

See the params section of the React Navigation docs for more.

Upvotes: 0

Related Questions