How to re-render component on going back using back button in react native?

Viewed 8200

If I go from home screen to product details screen and then to cart screen then the state update works fine but from cart screen if I add items or remove items and then navigate back to product details or home screen then state is not updated why so? See vudeo link below: https://drive.google.com/file/d/1AjrFMAXBs9Gzc5Onbm1uf-eW9gFfHxMU/view?usp=sharing

I am using redux but even if redux store state is updated still it doesn't render component with updated state why so?

I am think of using react navigation events but I am getting error why so? How to solve the problem? is this redux problem or react navigation problem? Does component re - render when navigated back to previous screen?

If I refresh the emulator screen then state is updated and displayed properly why does this happen?

I want to re render Home component when focused back but getting error. why so?

Screenshot:

enter image description here

Code:

home.js:

import React, {useState, useEffect} from 'react';
import {
    StyleSheet,
    ScrollView,
    View,
    Text,
    StatusBar,
    Image,
    TouchableOpacity,
    Button
} from 'react-native';
import Product from '../product/product';
import { useFocusEffect } from '@react-navigation/native';
import axios from 'axios';

export const Home = (props) => {

    const [categories, setCategories] = useState([]);

    useFocusEffect(
        React.useCallback(() => {
            const unsubscribe = FetchCategoryData();

            return () => unsubscribe();
        }, [])
    );

    const FetchCategoryData = () => {

        axios.get(`http://localhost:5000/api/categories`)
            .then(res => {
                console.log("All categories: ", res.data.data);

                setCategories([...res.data.data]);

                console.log("useeffect categories",categories)
            })
            .catch(error => console.log("Error: ", error))
    }

    return(
        <ScrollView style={styles.root}>
            <View style={{marginTop: 15, marginLeft: 15, marginBottom: 15}}> 
                <ScrollView horizontal={true} style={styles.container}>
                    <TouchableOpacity>
                        <View style={{marginRight: 15}}>
                            <Image source={require('../../assets/img/fruits.jpg')} style={{width: 325, height: 200, borderRadius: 10}}/>
                        </View>
                    </TouchableOpacity>
                    <TouchableOpacity>
                        <View style={{marginRight: 15}}>
                            <Image source={require('../../assets/img/grocery.jpg')} style={{width: 325, height: 200, borderRadius: 10}}/>
                        </View>
                    </TouchableOpacity>
                    <TouchableOpacity>
                        <View style={{marginRight: 15}}>
                            <Image source={require('../../assets/img/fruits.jpg')} style={{width: 325, height: 200, borderRadius: 10}}/>
                        </View>
                    </TouchableOpacity>
                </ScrollView>
            </View>
            {categories && categories.length > 0 ? categories.map(val => <CategoryList key={val._id} category={val.name} navigation={props.navigation}/>) : null}
        </ScrollView>
    )
}
2 Answers

React Navigation doesn't re-render screens when going back. This is so that your screens don't have to re-fetch their data or display a loading indicator every time you navigate. If you would like to perform some update when a screen, try reading this.

In short, React Navigation lets you subscribe to navigation events such as when a screen has just been focused:


export default class Screen extends Component {

    navigationSubscription;

    componentDidMount() {
        // Fetch initial data and add navigation listener
        // ...

        this.navigationSubscription = this.props.navigation.addListener('didFocus', this.onFocus);
    }

    componentWillUnmount() {
        this.navigationSubscription.remove();
    }

    // This function will be called everytime this screen is shown
    onFocus = (payload) => {
        console.log(payload);
        // You can then check for updates here
    }

    render() {
        return (
            <Text>I'm a screen</Text>
        );
    }
}
Related