尝试将堆栈导航器注入组件中,并显示错误消息“您应仅渲染一个导航器”

时间:2018-08-07 19:42:00

标签: javascript reactjs react-native react-navigation

在某些情况下,某项功能包含一个包含所有信息的FlatList,搜索栏,排序按钮和过滤器按钮。

对于排序和过滤器按钮,我需要从底部拉出一个占据屏幕一半的模式。

我了解到React Navigation希望我们仅创建一个“根”导航器,而所有其他导航器都是依赖项;但是,在这种特殊情况下,我非常想在此页面上明确添加一个导航器,用户在该页面上按下过滤器按钮,调出模态,按下过滤器选项,然后使模态导航到范围内的另一个过滤器子页面的视图,同时在后台保持主页内容和根导航状态。

我记得在React Navigation V1.x中实现了这个功能,但是没有人知道如何在V2.x中解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我没有使用嵌套堆栈导航器和其他工具来实现它,而是使用内置的react native modal实现了您的需求。

应用

import React, { Component } from 'react';
import { createStackNavigator } from 'react-navigation';
import { MainScreen } from './src/screens/MainScreen';

const RootStack = createStackNavigator(
  {
    MainScreen
  },
  {
    navigationOptions: {
      header: null
    }
  }
);

export default class App extends Component {
  render() {
    return (
      <RootStack />
    );
  }
}

主屏幕

import { default as React, PureComponent } from 'react';
import { View, Text, Button, Alert, Modal } from 'react-native';

interface Props {

}

interface States {
    num: number;
    isFilterOneVisible: boolean;
    isFilterTwoVisible: boolean;
}

export class MainScreen extends PureComponent<Props, States> {

    state = {
        num: 0,
        isFilterOneVisible: false,
        isFilterTwoVisible: false
    }

    render() {
        return (
            <View
                flex={1}
                justifyContent={'space-evenly'}
                alignItems={'center'}
            >
                <Text style={{ fontSize: 50 }}>{this.state.num}</Text>

                <Button
                    title={'CHANGE STATE'}
                    onPress={() => {
                        this.setState((prevState: States) => ({
                            num: prevState.num + 1
                        }));
                    }}
                />


                {/* Search */}
                <Button
                    title={'Search'}
                    onPress={() => {
                        Alert.alert('Search', 'Search clicked');
                    }}
                />

                {/* Sort*/}
                <Button
                    title={'Sort'}
                    onPress={() => {
                        Alert.alert('Sort Clicked', 'Sort clicked')
                    }}
                />


                <Button
                    title={'Filter'}
                    onPress={() => {
                        this.setState({
                            isFilterOneVisible: true
                        })
                    }}
                />

                {/* Filter Modal 1*/}
                <Modal
                    visible={this.state.isFilterOneVisible}
                    transparent={true}
                    animationType={'slide'}
                    onRequestClose={() => {
                        this.setState({
                            isFilterOneVisible: false
                        })
                    }}
                >
                    <View
                        flex={1}
                        justifyContent={'flex-end'}
                        backgroundColor={'rgba(0,0,0,0.2)'}
                    >
                        {/* Bottom */}
                        <View
                            justifyContent={'center'}
                            alignItems={'center'}
                            backgroundColor={'white'}
                            height={200}
                        >
                            <Button
                                title={'GO TO NEXT FILTER STATE'}
                                onPress={() => {
                                    this.setState({
                                        isFilterOneVisible: false,
                                        isFilterTwoVisible: true
                                    })
                                }}
                            />
                        </View>


                    </View>
                </Modal>

                {/* Filter Modal Two */}
                <Modal
                    visible={this.state.isFilterTwoVisible}
                    transparent={true}
                    animationType={'slide'}
                    onRequestClose={() => {
                        this.setState({
                            isFilterTwoVisible: false
                        })
                    }}
                >
                    <View
                        flex={1}
                        justifyContent={'flex-end'}
                        backgroundColor={'rgba(0,0,0,0.2)'}
                    >
                        {/* Bottom */}
                        <View
                            justifyContent={'center'}
                            alignItems={'center'}
                            backgroundColor={'white'}
                            height={200}
                        >
                            <Button
                                title={'SET DATA AS 1000'}
                                onPress={() => {
                                    this.setState({
                                        isFilterTwoVisible: false,
                                        num: 1000
                                    })
                                }}
                            />
                        </View>


                    </View>
                </Modal>



            </ View >
        );
    }
}

注意:该代码未经过优化,并且遵循一些错误的模式,例如arrow-methods-in-jsx。这只是一个可行示例的建议。随意增强代码并遵循divide-and-conquer策略;)。完整的源代码可以从here

中找到