реагировать контекст с реагировать навигации BottomNavigation - PullRequest
0 голосов
/ 12 января 2020

Я использую реагирующий на родство с реагирующей навигацией

Я создал 2 createAppContainer, один для всего приложения и еще один для BottomNavigation, контекст работал отлично, но реакция-навигация вызывает ошибку, потому что я Я использую 2 AppContainerStacks отдельно, я попытался изменить компонент Home, чтобы устранить эту проблему, и проблема с реакцией навигации исчезла, но контекст больше не работает, и я не могу получить данные, поступающие оттуда.

Все, что я сделал, это просто извлек данные из <HomeBottomTabNavigator /> снаружи в том же месте.

Я использовал их таким образом

Домой. js

/** @flow **/
import React, { useEffect, useState } from 'react';
import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet';

import { useMutation } from '@apollo/react-hooks';
import { GET_USER_DATA } from '../actions/mutations';
import { UserProvider } from '../core/context/userContext';
import { ResponseUtil } from '../core/utils/responseUtils';
import { Layout, withStyles } from '@ui-kitten/components';
import { getAccessToken } from '../core/utils/asyncStorageUtils';
import { HomeBottomTabNavigator } from '../core/navigations/tabNavigator';

type HomeScreenPropsType = {
  themedStyle: {
    container: ViewStyleProp
  }
};

function HomeScreen(props: HomeScreenPropsType): React$Element<any> {
  const { themedStyle } = props;
  const [userData, setUserData] = useState({});
  const [getUserData] = useMutation(GET_USER_DATA);

  useEffect(() => {
    const fetchUserData = async () => {
      const accessToken = await getAccessToken();
      const mutationVariables = { input: { provider: 'facebook', accessToken: accessToken } };
      const response = await getUserData({ variables: mutationVariables });
      const tidyData = ResponseUtil.socialAuthResponseFormatter(response);
      setUserData(tidyData);
    };
    fetchUserData();
  }, [getUserData]);

  return (
    <Layout testID={'home-screen'} style={themedStyle.container}>
      <UserProvider value={userData}>
        <HomeBottomTabNavigator />
      </UserProvider>
    </Layout>
  );
}

export const Home: React$StatelessFunctionalComponent<any> = withStyles(HomeScreen, () => ({
  container: {
    flex: 1
  }
}));

tabNavigator. js

/** @flow **/
import React from 'react';
import type { NavigationContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer, SafeAreaView } from 'react-navigation';
import { BottomNavigation, BottomNavigationTab, Icon } from '@ui-kitten/components';

import { SCREENS } from './screens';
import { Friends } from '../../screens/Friends';
import { Messages } from '../../screens/Messages';
import { Settings } from '../../screens/Settings';

const TabBarComponent = ({ navigation }): React$Element<any> => {
  const onSelect = (index) => {
    const selectedTabRoute = navigation.state.routes[index];
    navigation.navigate(selectedTabRoute.routeName);
  };
  const bottomTabIcon = (style, iconName): React$Element<Icon> => <Icon {...style} name={iconName} />;

  return (
    <SafeAreaView>
      <BottomNavigation selectedIndex={navigation.state.index} onSelect={onSelect}>
        <BottomNavigationTab title={SCREENS.MESSAGES} icon={(style) => bottomTabIcon(style, 'email-outline')} />
        <BottomNavigationTab title={SCREENS.FRIENDS} icon={(style) => bottomTabIcon(style, 'person-outline')} />
        <BottomNavigationTab title={SCREENS.SETTINGS} icon={(style) => bottomTabIcon(style, 'options-2-outline')} />
      </BottomNavigation>
    </SafeAreaView>
  );
};

const TabNavigator = createBottomTabNavigator(
  {
    [SCREENS.MESSAGES]: Messages,
    [SCREENS.FRIENDS]: Friends,
    [SCREENS.SETTINGS]: Settings
  },
  {
    tabBarComponent: TabBarComponent
  }
);

export const HomeBottomTabNavigator: NavigationContainer = createAppContainer(TabNavigator);

контекст работал отлично, но реакция-навигация вызывает ошибку, потому что я использую 2 AppContainerStacks отдельно, я пытался изменить компонент Home, чтобы устранить эту проблему, например следующая

Home. js

/** @flow **/
import { UserProvider } from '../core/context/userContext';
import { useMutation } from '@apollo/react-hooks';
import React, { useEffect, useState } from 'react';
import type { NavigationContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer, SafeAreaView } from 'react-navigation';
import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet';
import { BottomNavigation, BottomNavigationTab, Icon, Layout } from '@ui-kitten/components';

import { Messages } from './Messages';
import { Friends } from './Friends';
import { Settings } from './Settings';
import { GET_USER_DATA } from '../actions/mutations';
import { SCREENS } from '../core/navigations/screens';
import { ResponseUtil } from '../core/utils/responseUtils';
import { getAccessToken } from '../core/utils/asyncStorageUtils';

type HomeScreenPropsType = {
  themedStyle: {
    container: ViewStyleProp
  }
};

function HomeScreen(props: HomeScreenPropsType): React$Element<any> {
  const { navigation } = props;
  const [userData, setUserData] = useState({});
  const [getUserData] = useMutation(GET_USER_DATA);

  useEffect(() => {
    const fetchUserData = async () => {
      const accessToken = await getAccessToken();
      const mutationVariables = { input: { provider: 'facebook', accessToken: accessToken } };
      const response = await getUserData({ variables: mutationVariables });
      const tidyData = ResponseUtil.socialAuthResponseFormatter(response);
      setUserData(tidyData);
    };
    fetchUserData();
  }, [getUserData]);

  const onSelect = (index) => {
    const selectedTabRoute = navigation.state.routes[index];
    navigation.navigate(selectedTabRoute.routeName);
  };
  const bottomTabIcon = (style, iconName): React$Element<Icon> => <Icon {...style} name={iconName} />;

  return (
    <Layout testID={'home-screen'}>
      <UserProvider value={userData}>
        <SafeAreaView>
          <BottomNavigation selectedIndex={navigation.state.index} onSelect={onSelect}>
            <BottomNavigationTab title={SCREENS.MESSAGES} icon={(style) => bottomTabIcon(style, 'email-outline')} />
            <BottomNavigationTab title={SCREENS.FRIENDS} icon={(style) => bottomTabIcon(style, 'person-outline')} />
            <BottomNavigationTab title={SCREENS.SETTINGS} icon={(style) => bottomTabIcon(style, 'options-2-outline')} />
          </BottomNavigation>
        </SafeAreaView>
      </UserProvider>
    </Layout>
  );
}

const TabNavigator = createBottomTabNavigator(
  {
    [SCREENS.MESSAGES]: Messages,
    [SCREENS.FRIENDS]: Friends,
    [SCREENS.SETTINGS]: Settings
  },
  {
    tabBarComponent: HomeScreen
  }
);

export const Home: NavigationContainer = createAppContainer(TabNavigator);

и проблема реагирования-навигации исчезла, но контекст больше не работает, и я не могу получить данные, поступающие оттуда.

вот как я использовал контекст

Friends. js

/** @flow **/
import React from 'react';
import { SafeAreaView } from 'react-navigation';
import { Image, StyleSheet } from 'react-native';
import { Layout, List, ListItem, withStyles } from '@ui-kitten/components';
import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet';

import { useUserContext } from '../core/context/userContext';

type FriendsScreenPropsType = {
  themedStyle: {
    container: ViewStyleProp,
    safeAreaViewContainer: ViewStyleProp,
    list: ViewStyleProp,
    contentContainer: ViewStyleProp,
    listItem: ViewStyleProp
  }
};

export const FriendsScreen = (props: FriendsScreenPropsType): React$Element<any> => {
  const { themedStyle } = props;
  const user = useUserContext();

  const renderProfilePicture = (picture, style): React$Element<Image> => (
    <Image style={style} source={{ uri: picture }} />
  );

  const renderItem = ({ item }): React$Element<ListItem> => {
    const iconStyle = StyleSheet.create({ width: 50, height: 50, borderRadius: 50 });
    return (
      <ListItem
        style={themedStyle.listItem}
        title={item.name}
        icon={(): React$Element<Image> => renderProfilePicture(item.picture, iconStyle)}
      />
    );
  };

  return (
    <Layout level='3' style={themedStyle.container}>
      <SafeAreaView style={themedStyle.safeAreaViewContainer}>
        <List
          data={user.friends}
          renderItem={renderItem}
          contentContainerStyle={themedStyle.contentContainer}
          style={themedStyle.list}
        />
      </SafeAreaView>
    </Layout>
  );
};

export const Friends: React$StatelessFunctionalComponent<any> = withStyles(FriendsScreen, () => ({
  container: {
    flex: 1
  },
  safeAreaViewContainer: {
    flex: 1
  },
  list: {
    backgroundColor: 'transparent'
  },
  contentContainer: {
    paddingVertical: 1
  },
  listItem: {
    marginVertical: 2
  }
}));

и это файл контекста я сделал -> userContext. js

/** @flow **/
import React, { createContext, useContext } from 'react';

const UserContext = createContext({});

export function useUserContext(): any {
  return useContext(UserContext);
}

type ThemeProviderPropsType = {
  children: React$Node,
  value: any
};

export function UserProvider(props: ThemeProviderPropsType): React$Node {
  const { children, value } = props;
  return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...