#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 и спасибо)