Reputation: 105
I am new to react and react native and trying to understand the lifecycle of React components... I have four switches on my screen. I am trying to save the current state of the switches as an object (applied Filters) and then pass it to the params of the navigation props and access it in the onPress function of the save button in the navigation header...
import React, { useState, useEffect, useCallback } from 'react';
import { View, Text, StyleSheet, Switch } from 'react-native';
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
import HeaderButton from '../components/HeaderButton';
const FilterSwitch = (props) => {
return (
<View style={styles.filterContainer}>
<Text>{props.label}</Text>
<Switch
value={props.state}
trackColor={{ true: 'yellow' }}
thumbColor={{ true: 'blue' }}
onValueChange={props.onChange}
/>
</View>
);
};
class FilterScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
isGlutenFree: false,
isLactoseFree: false,
isVegan: false,
isVegetarian: false,
};
this.setisGlutenFree = this.setisGlutenFree.bind(this);
this.setisLactoseFree = this.setisLactoseFree.bind(this);
this.setisVegan = this.setisVegan.bind(this);
this.setIsVegetarian = this.setIsVegetarian.bind(this);
this.saveFilters = this.saveFilters.bind(this);
}
setisGlutenFree(newValue) {
this.setState({
isGlutenFree: newValue,
});
}
setisLactoseFree(newValue) {
this.setState({
isLactoseFree: newValue,
});
}
setisVegan(newValue) {
this.setState({
isVegan: newValue,
});
}
setIsVegetarian(newValue) {
this.setState({
isVegetarian: newValue,
});
}
saveFilters() {
const appliedFilters = {
glutenFree: this.state.isGlutenFree,
lactoseFree: this.state.isLactoseFree,
vegan: this.state.isVegan,
Vegetarian: this.state.isVegetarian,
};
console.log(appliedFilters);
}
componentDidMount() {
this.props.navigation.setParams({ save: this.saveFilters });
}
componentDidUpdate() {
this.props.navigation.setParams({ save: this.saveFilters });
}
render() {
return (
<View style={styles.screen}>
<Text style={styles.title}>Available Filters / Restrictions</Text>
<FilterSwitch
label="Gluten-free"
state={this.state.isGlutenFree}
onChange={(newValue) => this.setisGlutenFree(newValue)}
/>
<FilterSwitch
label="Lactose-free"
state={this.state.isLactoseFree}
onChange={(newValue) => this.setisLactoseFree(newValue)}
/>
<FilterSwitch
label="Vegan"
state={this.state.isVegan}
onChange={(newValue) => this.setisVegan(newValue)}
/>
<FilterSwitch
label="Vegetarian"
state={this.state.isVegetarian}
onChange={(newValue) => this.setIsVegetarian(newValue)}
/>
</View>
);
}
}
FilterScreen.navigationOptions = (navData) => {
return {
headerTitle: 'Filter Meals',
headerLeft: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName="ios-menu"
onPress={() => {
navData.navigation.toggleDrawer();
}}
/>
</HeaderButtons>
),
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Save"
iconName="ios-save"
onPress={() => {
console.log('Item Saved');
console.log(navData.navigation.getParam('save')());
}}
/>
</HeaderButtons>
),
};
};
const styles = StyleSheet.create({
screen: {
flex: 1,
alignItems: 'center',
},
title: {
fontFamily: 'open-sans-bold',
fontSize: 22,
margin: 20,
textAlign: 'center',
},
filterContainer: {
marginVertical: 10,
borderWidth: 1,
borderRadius: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
width: '80%',
height: '10%',
paddingLeft: 10,
},
});
export default FilterScreen;
the problem is that as soon as we enter the filter to screen the lifecycle methods are going in an infinite loop.... and the following error pops out following a huge stack trace.
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState
inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Guys I want to access the state parameters outside the component in the navigation header everytime the state gets updated.... so I thought everytime component gets updated the navigation params will get updated state parameters
Upvotes: 0
Views: 1309
Reputation: 435
Only update something if they have changed in componentDidUpdate to avoid infinite loop,
componentDidUpdate(prevProps, prevState) {
if (prevProps.something !== this.props.something) {
console.log('something has changed.')
}
}
Upvotes: 1
Reputation: 1549
componentDidUpdate by definition is being called every time component is being updated, i.e. when state or props change.
If you will update the state or you props in this function you will cause an infinite loop...
Upvotes: 1