StackNavigator的子组件在其父组件外部调用时呈现两次

时间:2017-09-14 15:19:18

标签: reactjs react-native react-navigation

我使用React Navigation在我的React Native应用程序中的屏幕之间导航。我的屏幕结构是:

@synchronized(myDict) {
   myDict[@"someOtherKey"] = someValue;
}

现在我想导航并将一些参数从DiscoverScreen传递给MoviesListScreen。

这是我的代码:

DiscoverScreen.js

 - DrawerNavigator    
    - HomeScreen    
    - MoviesStackNavigator    
      - MoviesListScreen    
      - MovieDetailsScreen    
    - DiscoverScreen

DrawerNavigator:

onSearchConfirm() {
    this.setState({searching: true})


    var params = {
        sort_by: this.state.sortBy,
        year: this.state.releaseYear,
        with_genres: this.state.genreIds.join(',')
    };

    const _this = this;

    return fetch(Configuration.TMDB_BASE_URL
                .concat('/discover/movie?')
                .concat(Utility.stringFromQueryParams({...params, api_key: Configuration.TMDB_API_KEY})))
        .then(response => response.json())
        .then(jsonResponse => {
            _this.setState({searching: false});

            const navigateAction = NavigationActions.navigate({
                routeName: 'MoviesList',
                params: {data: jsonResponse}
            })

            _this.props.navigation.dispatch(navigateAction)

        })
        .catch(err => console.error(err.toString()))
}

MoviesStackNavigator:

export default MenuNavScreen = DrawerNavigator(
{
    Home: {
        screen: HomeScreen
    },
    Movies: {
        screen: MoviesStackNavigator
    },
    DiscoverMovies: {
        screen: DiscoverScreen
    },
    About: {
        screen: AboutScreen
    },
},
{
    initialRouteName: 'Home'
})

最后,我正在检查params的代码 MoviesListScreen:

export default MoviesStackNavigator = StackNavigator({
    MoviesList: {
        screen: MoviesListScreen
    },
    MovieDetails: {
        screen: MovieDetailsScreen
    },
});

好吧,最后一段代码执行了两次。首先使用"数据" param undefined,第二次使用正确填充的param。我的错误在哪里?谢谢大家:))

编辑:要清楚,这是上述问题的结果:

IMAGE

1 个答案:

答案 0 :(得分:2)

过了一段时间,我意识到我可以通过用新的DiscoverStackNavigator替换DiscoverScreen来解决问题,然后将DiscoverScreen,MoviesListScreen和MovieDetailsS​​creen设置为子屏幕。所以我的代码现在看起来像这样:

DrawerNavigator:

export default MenuNavScreen = DrawerNavigator(
{
    Home: {
        screen: HomeScreen
    },
    Movies: {
        screen: MoviesStackNavigator
    },
    DiscoverMovies: {
        screen: DiscoverStackNavigator
    },
    About: {
        screen: AboutScreen
    },
},
{
    initialRouteName: 'Home'
})

DiscoverStackNavigator:

export default DiscoverStackNavigator = StackNavigator({
    DiscoverMovies: {
        screen: DiscoverScreen
    }
    DiscoverMoviesList: {
        screen: MoviesListScreen
    },
    DiscoverMovieDetails: {
        screen: MovieDetailsScreen
    },
});

导航到MoviesScreen:

onSearchConfirm() {
    //...code before

    return fetch(Configuration.TMDB_BASE_URL
                .concat('/discover/movie?')
                .concat(Utility.stringFromQueryParams({...params, api_key: Configuration.TMDB_API_KEY})))
        .then(response => response.json())
        .then(jsonResponse => {
            _this.setState({searching: false});

            const navigateAction = NavigationActions.navigate({
                routeName: 'DiscoverMoviesList', // we changed the route name
                params: {data: jsonResponse}
            })

            _this.props.navigation.dispatch(navigateAction)

        })
        .catch(err => console.error(err.toString()))
}

我不知道这是否是正确的方法,但效果很好。