【问题标题】:Setting params on useEffect and getting the params it on createStackNav in React Navigation 5在 useEffect 上设置参数并在 React Navigation 5 中的 createStackNav 上获取参数
【发布时间】:2020-11-22 01:13:58
【问题描述】:

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

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

   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>
                        )

但这不起作用并且不会返回任何内容。它还会冻结我所有的开关。

这是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。

【问题讨论】:

  • FiltersScreen.js 中,您能否尝试使用props.navigation.setParams({ save: saveFilters }); 并判断它是否有效?另外,你的useEffect 有依赖数组吗?应该的,不知道你是不是刚删了这里贴代码
  • 它什么也没做。最重要的是,它冻结了我的FiltersScreen屏幕,我根本无法触摸任何东西。根据依赖关系,它是一个状态对象,如上所示。
  • 您的saveFilters 是一个函数,但它什么也不做,只是创建一个对象。对吗?

标签: javascript reactjs react-native react-navigation


【解决方案1】:

我猜“冻结”问题是你的useEffect 在每个屏幕渲染中都执行,因为它没有依赖数组(阅读Tip: Optimizing Performance by Skipping Effects)。

您的代码应如下所示:

// 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

【讨论】:

    猜你喜欢
    • 2020-05-29
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    相关资源
    最近更新 更多