I am a newbie to React-native and have been trying to develop an app through learning. Today, I read the official doc of React Navigation. I referred and wrote some code but for some reason, two headers were being displayed on the screen. I read through the code I had again and again, but I couldn't find where it was wrong. I put the code below. There are some Japanese comments, but please don't mind them.
Thanks for taking your time and dedicating to this problem^^
// Home.js
import React, { useState, useEffect } from "react";
import {
Button,
View,
Text,
TouchableOpacity,
FlatList,
RefreshControl,
StyleSheet,
} from "react-native";
import { ListItem } from "react-native-elements";
import xml2js from "react-native-xml2js";
export const HomeScreen = ({ navigation }) => {
const [rssList, setRssList] = useState();
const fetchRss = async () => {
await fetch("https://tech-parrot.com/feed/")
.then((res) => res.text())
.then((xml) => {
const parser = xml2js.Parser();
parser.parseString(xml, (err, result) => {
setRssList(result.rss.channel[0].item);
});
});
};
useEffect(() => {
fetchRss();
}, []);
return (
<View style={styles.container}>
<FlatList
ItemSeparatorComponent={() => <View style={styles.separator} />}
data={rssList}
renderItem={({ item }) => (
<ListItem>
<TouchableOpacity
onPress={() => {
navigation.navigate("Details", { item: item });
}}
>
<View style={styles.row}>
<Text style={styles.title}>{item.title[0]}</Text>
<Text style={styles.link}>
{new Date(Date.parse(item.pubDate[0])).toLocaleDateString(
"ja"
)}
</Text>
</View>
</TouchableOpacity>
</ListItem>
)}
keyExtractor={(item) => item.link[0]}
/>
</View>
);
};
const styles = StyleSheet.create({
base: {
padding: 0,
},
body: {
backgroundColor: "#fff",
},
header: {
color: "#fff",
fontSize: 20,
fontWeight: "500",
},
container: {
flex: 1,
backgroundColor: "#FFF",
},
row: {
flex: 1,
paddingHorizontal: 10,
paddingVertical: 5,
},
title: {
color: "#000",
fontSize: 16,
},
link: {
color: "#db7093",
fontSize: 12,
},
separator: {
flex: 1,
height: 1,
backgroundColor: "#ddd",
},
});
// App.js
import React from "react";
import { StyleSheet } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; // 新規追加
import { HomeScreen } from "./screens/Home";
import { DetailsScreen } from "./screens/Details";
import { ReadLaterScreen } from "./screens/ReadLater"; // 新規追加
import { MemoScreen } from "./screens/Memo"; // 新規追加
import Ionicons from "react-native-vector-icons/Ionicons"; // 新規追加
export default function App() {
const Stack = createStackNavigator();
// タブ移動の設定を新規追加
// createBottomTabNavigator ... タブ移動を設定する関数
const Tab = createBottomTabNavigator();
// 新規追加
// - 移動を関数に持たせて、タブ移動の設定で利用
// - 意図 ... タブ移動の箇所のコードが読みにくくなるため
const Home = () => {
return (
<Stack.Navigator>
<Stack.Screen name="ホーム" component={HomeScreen} />
<Stack.Screen name="詳細" component={DetailsScreen} />
</Stack.Navigator>
);
};
// 新規追加
// - 移動を関数に持たせて、タブ移動の設定で利用
// - 意図 ... タブ移動の箇所のコードが読みにくくなるため
const ReadLater = () => {
return (
<Stack.Navigator>
<Stack.Screen name="あとで読む" component={ReadLaterScreen} />
<Stack.Screen name="詳細" component={DetailsScreen} />
</Stack.Navigator>
);
};
// 新規追加
// - 移動を関数に持たせて、タブ移動の設定で利用
// - 意図 ... タブ移動の箇所のコードが読みにくくなるため
const Memo = () => {
return (
<Stack.Navigator>
<Stack.Screen name="メモ" component={MemoScreen} />
<Stack.Screen name="詳細" component={DetailsScreen} />
</Stack.Navigator>
);
};
return (
// タブ移動の設定を新規追加 ====================
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
// ホームアイコンの設定を行っている ==========
if (route.name === "ホーム") {
iconName = focused // 『三項演算子』で条件分岐。選択中 or 未選択の場合のアイコンを変えることができる(今回は変えてません)
? "ios-home"
: "ios-home";
} else if (route.name === "Settings") {
iconName = focused ? "ios-list-box" : "ios-list";
}
// 下記は、ホームと同様 ====================
if (route.name === "あとで読む") {
iconName = focused ? "ios-pricetag" : "ios-pricetag";
} else if (route.name === "Settings") {
iconName = focused ? "ios-list-box" : "ios-list";
}
if (route.name === "メモ") {
iconName = focused ? "md-document" : "md-document";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: "tomato",
inactiveTintColor: "gray",
}}
>
<Tab.Screen name="ホーム" component={Home} />
<Tab.Screen name="あとで読む" component={ReadLater} />
<Tab.Screen name="メモ" component={Memo} />
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
// container: {
// flex: 1,
// backgroundColor: "#fff",
// alignItems: "center",
// justifyContent: "center",
// },
});
CodePudding user response:
Navigators have a default header. Since you are nesting them, you are seeing multiple headers. You can hide them by adding
headerShown: false
in the options prop of the screen or the screenOptions prop of the navigator.