在useEffect上设置params,并在React Navigation 5中的createStackNav上获取p



我正在开发一个应用程序,在该应用程序中,我需要在对象中发送或设置我的状态的特定参数。

这是我的对象及其受人尊敬的状态:

const [isGlutenFree, setIsGlutenFree] = useState(false);
const [isLactoseFree, setisLactoseFree] = useState(false);
const [isVegan, setIsVegan] = useState(false);
const [isVegetarian, setIsVegetarian] = useState(false);

const saveFilters = () => {
const appliedFilters = {
glutenFree: isGlutenFree,
lactosFree: isLactoseFree,
vegan: isVegan,
isVegetarian: isVegetarian
};
};

这些都在我的FiltersScreen.js文件中。因此,在我的useEffect上,我尝试使用CommonActions来设置参数:

import { CommonActions } from '@react-navigation/native';
useEffect(() => {
props.navigation.dispatch(CommonActions.setParams({ save: saveFilters }));
});

然后在我的Navigator.js文件中,我试图接收这个并控制台。将它记录在屏幕上,看看它是否有我需要的数据:

<FilterNav.Screen
name="Filters"
component={FiltersScreen}
options={({ route }) => ({
title: 'Filters',
headerLeft: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title='Menu'
iconName='ios-menu'
onPress={() => {
navigation.toggleDrawer();
}}
/>
</HeaderButtons>
),
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title='Save'
iconName='ios-save'
onPress={() => {
// CONSOLE LOG THE PARAMS SET >>
console.log(route.params.save);
}}
/>
</HeaderButtons>
)
})}
/>
</FilterNav.Navigator>

具体来说:

headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title='Save'
iconName='ios-save'
onPress={() => {
// CONSOLE LOG THE PARAMS SET >>
console.log(route.params.save);
}}
/>
</HeaderButtons>
)

但这不起作用,也没有任何回报。它还冻结了我所有的Switch。

以下是FiltersScreen.js:的完整代码

import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Switch, Platform } from 'react-native';
import { CommonActions } from '@react-navigation/native';
import Colors from '../constants/colors';
const FiltersSwitch = props => {
return(
<View style={styles.filterContainer}>
<Text>{ props.label }</Text>
<Switch
trackColor={{ true: Colors.primaryColor }}
thumbColor={Platform.OS === 'android' ? Colors.primaryColor : ''}
value={props.state}
onValueChange={props.onChange} />
</View>
);
};
const FiltersScreen = props => {
const [isGlutenFree, setIsGlutenFree] = useState(false);
const [isLactoseFree, setisLactoseFree] = useState(false);
const [isVegan, setIsVegan] = useState(false);
const [isVegetarian, setIsVegetarian] = useState(false);

// We will give this a connection with the 
// MealsNavigator in order to trigger this 
// function via useEffect 
const saveFilters = () => {
const appliedFilters = {
glutenFree: isGlutenFree,
lactosFree: isLactoseFree,
vegan: isVegan,
isVegetarian: isVegetarian
};
};
useEffect(() => {
props.navigation.dispatch(CommonActions.setParams({ save: saveFilters }));
});
return (
<View style={styles.screen}>
<Text style={styles.title}>Available Filters / Restrictions</Text>
<FiltersSwitch
label="Glutten Free"
state={isGlutenFree}
onChange={newValue => setIsGlutenFree(newValue)} />
<FiltersSwitch
label="Lactose Free"
state={isLactoseFree}
onChange={newValue => setisLactoseFree(newValue)} />
<FiltersSwitch
label="Vegan"
state={isVegan}
onChange={newValue => setIsVegan(newValue)} />
<FiltersSwitch
label="Vegetarian"
state={isVegetarian}
onChange={newValue => setIsVegetarian(newValue)} />
</View>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
alignItems: 'center'
},
title: {
fontFamily: 'poppins-bold',
fontSize: 22,
margin: 20,
textAlign: 'center'
},
filterContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
width: '80%',
marginVertical: 15
}
});
export default FiltersScreen;

以下是navigation.js文件的完整代码:

const FilterNav = createStackNavigator();
const FiltersNavigator = () => {
return (
<FilterNav.Navigator
mode="modal"
screenOptions={{
headerStyle: {
backgroundColor: Colors.primaryColor,
},
headerTintColor: '#fff',
headerTitleStyle: {
fontSize: 17
}
}}
>
<FilterNav.Screen
name="Filters"
component={FiltersScreen}
options={({ route }) => ({
title: 'Filters',
headerLeft: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title='Menu'
iconName='ios-menu'
onPress={() => {
navigation.toggleDrawer();
}}
/>
</HeaderButtons>
),
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title='Save'
iconName='ios-save'
onPress={() => {
console.log(route.params.save);
}}
/>
</HeaderButtons>
)
})}
/>
</FilterNav.Navigator>
);
};

请帮助如何解决这个已经被卡住了一段时间的问题。我使用的是React Navigation 5。

我想;冻结";问题是useEffect在每个屏幕渲染中都在执行,因为它并没有依赖数组(请阅读提示:通过跳过效果优化性能(。

你的代码应该是这样的:

// useCallback, so it doesn't create a new saveFilters function in every render
const saveFilters = useCallback(() => {
const appliedFilters = {
glutenFree: isGlutenFree,
lactosFree: isLactoseFree,
vegan: isVegan,
isVegetarian: isVegetarian
};
}, [isGlutenFree, isLactoseFree, isVegan, isVegetarian]); // This function depends on those variables.
useEffect(() => {
props.navigation.dispatch(CommonActions.setParams({ save: saveFilters }));
}, [saveFilters]); // It should change the parameterized function if it changes

最新更新