Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native NavigationEvents: onDidFocus getting Infinite Loop

I am using NavigationEvents to load my list automatically.

So far it does work and it loads my updated list but on the console it keeps running the API call function on INFINITE LOOP.

However, whenever I open list screen, I just want to load the API call function ONCE.

So if there is any better solution please feel free to help.

Code snippet below:

import { NavigationEvents } from 'react-navigation';

import NameActionBar from '../components/mNameActionBar';
import FreelancerList from '../components/mFreelancerList';

export default class MasterScreen extends Component {

    componentDidMount() {
        this.getFreelancerList();
        console.log('ComponentDidMount()');
    }

    getFreelancerList() {
        console.log('Freelancer List');
        let self = this;
        AsyncStorage.getItem('my_token').then((keyValue) => {
            console.log('Master Screen (keyValue): ', keyValue); //Display key value
            axios({
                method: 'get',
                url: Constants.API_URL + 'user_m/freelancer_list/',
                responseType: 'json',
                headers: {
                    'X-API-KEY': Constants.API_KEY,
                    'Authorization': keyValue,
                },
            })
                .then(function (response) {
                    //console.log('Response Data: ', response.data.data);
                    console.log('Response: ', response);
                    self.setState({
                        dataSource: response.data.data,
                    });
                })
                .catch(function (error) {
                    console.log('Error: ', error);
                });
        }, (error) => {
            console.log('error error!', error) //Display error
        });
    }

    viewFreelancerList() {
        const { dataSource } = this.state;
        return (
            <View>
                <FlatList
                    data={dataSource}
                    keyExtractor={({ id }, index) => index.toString()}
                    renderItem={({ item }) => <FreelancerList {...item} />}
                />
            </View>
        );
    }

    render() {
        return (
            <>
                {<NavigationEvents onDidFocus={this.getFreelancerList()} />}
                <NameActionBar />
                <ScrollView>
                    {this.viewFreelancerList()}
                </ScrollView>
            </>
        );
    }
}
like image 489
Beep Boop Avatar asked Apr 21 '26 15:04

Beep Boop


1 Answers

You need to remove the parentheses when you pass the method to onDidFocus. Make it look like this: onDidFocus={this.getFreelancerList}

This is a common gotcha with react. When you include the parentheses after the function name, you are actually executing the function. Based on your code, it looks like that isn't actually your intention. You are trying to pass a callback to onDidFocus, so that when, and only when, the component receives focus, the method is called.

The reason you're experiencing the infinite loop is that you are updating state in getFreelancerList. So your component renders, and you immediately call getFreelancerList. In getFreelancerList, you are updating state, causing the component to render yet again. Then, you guessed it, as the component rerenders, it calls getFreelancerList again, and the cycle repeats :)

like image 146
Spencer Stolworthy Avatar answered Apr 23 '26 04:04

Spencer Stolworthy