Как вложить навигатор стека в навигатор ящика с навигацией v5

#javascript #react-native #react-navigation

#javascript #react-native #реагировать-навигация

Вопрос:

структура моего проекта выглядит примерно так:

  • app.js (Загружает данные и навигатор ящика)

  • Главный экран (загружайте карточки, используя данные, полученные ранее в режиме предварительного просмотра, и при нажатии у вас есть NewsComponent, который извлекает полные данные для этой записи)

  • Новостной экран (загрузите полную статью, используя данные, полученные ранее)

в моем App.js Я использую такой навигатор для ящиков:

 return (
      <NavigationContainer>
        <Drawer.Navigator initialRouteName="Main">
          <Drawer.Screen name="Main" options={{ headerShown: false}}>
            {props => <MainScreen {...props} extraData={App.news} />}
          </Drawer.Screen>
          <Drawer.Screen name="Court Reservation" component={CourtReservation}></Drawer.Screen>
          <Drawer.Screen name="News" component={NewsScreen}></Drawer.Screen>
        </Drawer.Navigator>
      </NavigationContainer>
    );
  }
  

но мне нужно вставить навигатор стека внутри основного компонента, чтобы отображать записи (экран новостей), потому что, если нет, когда я возвращаюсь к списку (основному) и снова к другой записи, содержимое не обновляется, и отображается первая запись.

Я пробовал несколько раз, но получаю всевозможные ошибки. Прямо сейчас мой главный экран выглядит так:

 render() {
    return (
      <Container>
        <Header>
          <Left>
            <Button onPress={() => this.props.navigation.openDrawer()} transparent>
              <Icon name='menu' />
            </Button>
          </Left>
          <Body>
            <Title>Header</Title>
          </Body>
          <Right />
        </Header>
        <FlatList
          data={this.state.news}
          onEndReached={this.fetchMoreNews}
          onEndReachedThreshold={0.5}
          keyExtractor={(item, index) => index.toString()}
          renderItem={({item}) => (
            <Content>
          <CardNewsComponent data={item} nav={this.props.navigation}/>
          </Content>
          )}/>
        </Container>
    );
  }
  

Но использует навигацию по ящику, чтобы «перейти» к компоненту.

Как я могу интегрировать stack Navigator для этого?


Редактировать:

После того, как добрый пользователь мой app.js это похоже на:

     import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { createStackNavigator } from '@react-navigation/stack';
import MainScreen from './screens/MainScreen';
import NewsScreen from './screens/NewsScreen';
import CourtReservation from './screens/CourtReservation';
import * as SplashScreen from 'expo-splash-screen';
import * as Font from 'expo-font';
import { Ionicons } from '@expo/vector-icons';
import axios from 'axios';


const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();

const myStack = (<Stack.Navigator initialRouteName="Main">
              <Stack.Screen name="Main" options={{ headerShown: false}}>
                {props => <MainScreen {...props} extraData={App.news} />}
              </Stack.Screen>
              <Stack.Screen name="News" component={NewsScreen}></Stack.Screen>
            </Stack.Navigator>)
       

export default class App extends React.Component {
  state = {
    appIsReady: false,
  };

  news = {};

  async componentDidMount() {
    // Prevent native splash screen from autohiding
    try {
      await SplashScreen.preventAutoHideAsync();
    } catch (e) {
      console.warn(e);
    }
    this.prepareResources();
  }

  /**
   * Method that serves to load resources and make API calls
   */
  prepareResources = async () => {
    await performAPICalls();
    await downloadAssets();

    this.setState({ appIsReady: true }, async () => {
      await SplashScreen.hideAsync();
    });
  };

  render() {
    if (!this.state.appIsReady) {
      return null;
    }

    return (
      <NavigationContainer>
        <Drawer.Navigator initialRouteName="Main">
          <Drawer.Screen name="Main" component={myStack}></Drawer.Screen>
          <Drawer.Screen name="Court Reservation" component={CourtReservation}></Drawer.Screen>
        </Drawer.Navigator>
      </NavigationContainer>
    );
  }
}

// Put any code you need to prepare your app in these functions
async function performAPICalls() {
  await axios.get('https://alqueriadelbasket.com/?r=noticias/FetchNoticiasJsonamp;boundBot=0amp;boundTop=5')
    .then((response) => {
      App.news = response.data;
    }).catch((error)=> {
      console.log(error);
    })
}
async function downloadAssets() {
    await Font.loadAsync({
      Roboto: require('native-base/Fonts/Roboto.ttf'),
      Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
      ...Ionicons.font,
  });
}
  

И мой главный экран

 import React, { Component } from 'react';
import { Container, Content, Header, Left, Button, Icon, Right, Body, Title} from 'native-base';
import {FlatList} from 'react-native';
import CardNewsComponent from './components/CardNewsComponent';
import axios from 'axios';

export default class MainScreen extends Component {
  constructor(props){
    super(props);
    this.state = {
      news: this.props.extraData,
      boundBot: 6,
      bountTop: 11,
      error: null,
    };
  }

  fetchMoreNews = () => {
    axios.get(`https://alqueriadelbasket.com/?r=noticias/FetchNoticiasJsonamp;boundBot=${this.state.boundBot}amp;boundTop=${this.state.bountTop}`)
    .then((response) => {
      this.setState({
        boundBot: this.state.boundBot 5,
        boundTop: this.state.boundTop 5,
        news: this.state.news.concat(response.data)
      })
    }).catch((error)=> {
      console.log(error);
    })
  }

  newsData = this.props.extraData;
  render() {
    return (
      <Container>
        <Header>
          <Left>
            <Button onPress={() => this.props.navigation.openDrawer()} transparent>
              <Icon name='menu' />
            </Button>
          </Left>
          <Body>
            <Title>Header</Title>
          </Body>
          <Right />
        </Header>
        <FlatList
          data={this.state.news}
          onEndReached={this.fetchMoreNews}
          onEndReachedThreshold={0.5}
          keyExtractor={(item, index) => index.toString()}
          renderItem={({item}) => (
            <Content>
          <CardNewsComponent data={item} nav={this.props.navigation}/>
          </Content>
          )}/>
        </Container>
    );
  }
}
  

Ошибка заключается в том, что «Получено недопустимое значение для реквизита ‘component’ для основного экрана, это должен быть действительный компонент react.

Забавно, что раньше Main работал как шарм… :/


ПРАВКА2:

После попробуйте заглянуть в официальный документ.

Это была проблема:

Это не может быть константа, это должна быть функция… Итак, я добавил эту функцию в навигацию ящика, и она сработала как по волшебству.

вот код:

 function MyStack() {
  return (
    <Stack.Navigator initialRouteName="Main">
              <Stack.Screen name="Main" options={{ headerShown: false}}>
                {props => <MainScreen {...props} extraData={App.news} />}
              </Stack.Screen>
              <Stack.Screen name="News" component={NewsScreen}></Stack.Screen>
            </Stack.Navigator>
  );
}
  

Комментарии:

1. просто выстрел в темноте, вы можете переименовать myStack в MyStack ? это возможная причина

2. По-прежнему не работает, та же ошибка, переименована как в Const …, так и в DrawerNav component={…} есть другие предположения?

3. Я просто нахожу решение, которое я задам в главном вопросе.

Ответ №1:

Внутри навигатора ящика у нас есть экраны ящиков

   <Drawer.Navigator initialRouteName="Main">
     <Drawer.Screen name="Main" options={{ headerShown: false}}>
     ......
     //you can add a Stack Navigator as a screen here

  </Drawer.Navigator>

  

Таким образом, вы можете определить навигатор стека выше как таковой:

   const MyStack = <Stack.Navigator>
                  //your stack screens     
                  ......
                 </Stack.Navigator>
  

Затем используйте его в качестве экрана ящика:

 <Drawer.Screen name="main" component={MyStack} />
  

Комментарии:

1. При редактировании, которое у меня возникает, «Неопределенный не является объектом (оценка «Stack.Navigator» есть какие-либо предположения?

2. Я думаю, вы пропустили инструкцию import : import { createStackNavigator } from '@react-navigation/stack';

3. Да, извините, я думал, что снова отредактировал, ошибка: «Получено недопустимое значение для реквизита «компонент» для основного экрана, это должен быть действительный компонент react. (Еще раз проверьте основной awnser и спасибо)