WARN 需要循环:src\Navigation\StackNavigation.js -> src\Navigation\TabsNavigation.js -> src\Navigation\StackNavigation.js 允许循环,但可能会导致未初始化的值。考虑重构以消除对循环的需要。
我开始使用 React Native,嵌套导航器对我来说是一个很大的挑战。当显示仪表板时,会显示上述警告。
当我尝试导航到 ProductsStack 时,会显示此错误。
错误警告:渲染不同组件 (
BottomTabNavigator
) 时无法更新组件 (ProductsStack
)。要在 ProductsStack
中找到错误的 setState() 调用,请按照 https://reactjs.org/link/setstate-in-render 中所述跟踪堆栈跟踪
下面是我的代码: **StackNavigation.js **
`import React from 'react'
import { createStackNavigator } from "@react-navigation/stack";
import Brands from '../Screens/Brands'
import Products2 from '../Screens/Products2'
import Warehouses from '../Screens/Warehouses'
import AdminProfile from '../Screens/AdminProfile'
import Products from '../Screens/Products'
import Purchases from '../Screens/Purchases'
import Sales from '../Screens/Sales'
import Expenses from '../Screens/Expenses'
import Accounting from '../Screens/Accounting'
import TabsNavigation from './TabsNavigation';
import More from '../Screens/More';
import Login from '../auth/Login'
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
import Categories2 from '../Screens/Categories2';
const Stack=createStackNavigator()
const tabHiddenRoutes = ["Categories","Brands","Products2","Warehouses","AdminProfile","Products","Purchases","Sales","Expenses","Accounting"];
const MainStack = () => {
return (
<Stack.Navigator
screenOptions={{headerShown:false}} initialRouteName='Dashboard2'>
<Stack.Screen name='Dashboard2' component={TabsNavigation}/>
</Stack.Navigator>
)
}
const ProductsStack = ({navigation,route}) => {
if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
navigation.setOptions({tabBarStyle: {display: 'none'}});
} else {
navigation.setOptions({tabBarStyle: {display: 'flex'}});
}
return (
<Stack.Navigator>
<Stack.Screen name='Products3' component={Products} options={{headerShown:false}} />
{/* <Stack.Screen name='Categories' component={Categories} /> */}
<Stack.Screen name='Categories' component={Categories2} />
<Stack.Screen name='Brands' component={Brands} />
<Stack.Screen name='Products2' component={Products2} options={{title:'Products'}}/>
<Stack.Screen name='Warehouses' component={Warehouses} />
</Stack.Navigator>
)
}
const MoreStack = ({navigation,route}) => {
if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
navigation.setOptions({tabBarStyle: {display: 'none'}});
} else {
navigation.setOptions({tabBarStyle: {display: 'flex'}});
}
return (
<Stack.Navigator>
<Stack.Screen name='More2' component={More} options={{headerShown:false}}/>
<Stack.Screen name='AdminProfile' component={AdminProfile} />
<Stack.Screen name='Products' component={Products} />
<Stack.Screen name='Purchases' component={Purchases} />
<Stack.Screen name='Sales' component={Sales} />
<Stack.Screen name='Expenses' component={Expenses} />
<Stack.Screen name='Accounting' component={Accounting} />
</Stack.Navigator>
)
}
export {MainStack,ProductsStack,MoreStack}`
**TabsNavigation.js **
import { View, Text } from 'react-native'
import React from 'react'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Dashboard from '../Screens/Dashboard';
import POS from '../Screens/POS';
import Reports from '../Screens/Reports'
import Ionicons from 'react-native-vector-icons/Ionicons'
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; ;
import { Platform, TouchableOpacity } from 'react-native';
import { MoreStack, ProductsStack } from './StackNavigation';
import { useNavigation } from '@react-navigation/native'
const Tabs = createBottomTabNavigator();
const TabsNavigation = () => {
const navigation=useNavigation()
return (
<Tabs.Navigator screenOptions={{headerShown:'false',
tabBarStyle:{backgroundColor:'white',minHeight:60,fontSize:16,paddingBottom:10
},
tabBarInactiveTintColor:'grey',
tabBarActiveTintColor:"#38BDF8"}}>
<Tabs.Screen name='Dashboard' component={Dashboard} options={
{headerShown:false,
tabBarIcon:({color,size})=>(
<Icon name='home' color={color} size={30} />
)
}
}/>
<Tabs.Screen name='Products' component={ProductsStack} options={{
headerShown:false,
tabBarIcon:({color,size})=>(
<Icon name='microsoft-xbox-controller-view' color={color} size={30} />
)
}
}/>
<Tabs.Screen name='POS' component={POS} options={{
tabBarStyle:{display:'none'},
headerLeft: () => (
<TouchableOpacity onPress={() => {navigation.goBack()}}>
<Ionicons name='arrow-back-outline' size={25} color={'black'} style={{marginLeft:10}}/>
</TouchableOpacity>
),
tabBarLabel: () => null,
tabBarIcon:({color,size})=>{
return(
<View style={{
top:Platform.OS=="ios" ? -10:-20,
width:Platform.OS=="ios"?50:60,
height:Platform.OS=="ios"?50:60,
borderRadius:Platform.OS=="ios"?25:20,
backgroundColor:"#38BDF8",
alignItems:'center',
justifyContent:'center',
padding:5
}}>
<Icon name='point-of-sale' size={50} color={"white"} />
</View>
)
}
}
}/>
<Tabs. Screen name='Reports' component={Reports} options={
{
tabBarIcon:({color,size})=>(
<Icon name='chart-areaspline' color={color} size={30} />
)
}
}/>
<Tabs.Screen name='More' component={MoreStack} options={{
headerShown:false,
tabBarIcon:({color,size})=>(
<Icon name='view-grid-plus' color={color} size={30} />
)
}
}/>
</Tabs.Navigator>
)
}
export default TabsNavigation
我已经删除了未使用的导入,但仍然有警告
我通过将导航写入一个文件来修复了需要循环错误
import { View,Platform, TouchableOpacity } from 'react-native'
import React, { useEffect } from 'react'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { useNavigation } from '@react-navigation/native'
import { createStackNavigator } from "@react-navigation/stack";
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
import Dashboard from '../Screens/Dashboard';
import POS from '../Screens/POS';
import Reports from '../Screens/Reports'
import Ionicons from 'react-native-vector-icons/Ionicons'
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; ;
import More from '../Screens/More';
import Brands from '../Screens/Brands'
import Products2 from '../Screens/Products2'
import Warehouses from '../Screens/Warehouses'
import AdminProfile from '../Screens/AdminProfile'
import Products from '../Screens/Products'
import Purchases from '../Screens/Purchases'
import Sales from '../Screens/Sales'
import Expenses from '../Screens/Expenses'
import Accounting from '../Screens/Accounting'
import Categories2 from '../Screens/Categories2';
import Login from '../auth/Login'
// import SignUp from '../auth/SignUp'
const Tabs = createBottomTabNavigator();
const Stack=createStackNavigator()
const tabHiddenRoutes = ["Categories","Brands","Products2","Warehouses","AdminProfile","Products","Purchases","Sales","Expenses","Accounting"];
const MainStack = () => {
return (
<Stack.Navigator
screenOptions={{headerShown:false}} initialRouteName='Login'>
<Stack.Screen name='Login' component={Login}/>
{/* <Stack.Screen name='SignUp' component={SignUp}/> */}
<Stack.Screen name='Dashboard2' component={TabsNavigation}/>
</Stack.Navigator>
)
}
const ProductsStack = ({navigation,route}) => {
useEffect(()=>{
if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
navigation.setOptions({tabBarStyle: {display: 'none'}});
} else {
navigation.setOptions({tabBarStyle: {display: 'flex'}});
}
},[navigation,route])
return (
<Stack.Navigator>
<Stack.Screen name='Products3' component={Products} options={{headerShown:false}} />
<Stack.Screen name='Categories' component={Categories2} />
<Stack.Screen name='Brands' component={Brands} />
<Stack.Screen name='Products2' component={Products2} options={{title:'Products'}}/>
<Stack.Screen name='Warehouses' component={Warehouses} />
</Stack.Navigator>
)
}
const MoreStack = ({navigation,route}) => {
useEffect(()=>{
if(tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))){
navigation.setOptions({tabBarStyle: {display: 'none'}});
} else {
navigation.setOptions({tabBarStyle: {display: 'flex'}});
}
},[navigation,route])
return (
<Stack.Navigator>
<Stack.Screen name='More2' component={More} options={{headerShown:false}}/>
<Stack.Screen name='AdminProfile' component={AdminProfile} />
<Stack.Screen name='Products' component={Products} />
<Stack.Screen name='Purchases' component={Purchases} />
<Stack.Screen name='Sales' component={Sales} />
<Stack.Screen name='Expenses' component={Expenses} />
<Stack.Screen name='Accounting' component={Accounting} />
</Stack.Navigator>
)
}
const TabsNavigation = () => {
const navigation=useNavigation()
return (
<Tabs.Navigator screenOptions={{headerShown:'false',
tabBarStyle:{backgroundColor:'white',minHeight:60,fontSize:16,paddingBottom:10
},
tabBarInactiveTintColor:'grey',
tabBarActiveTintColor:"#38BDF8"}}>
<Tabs.Screen name='Dashboard' component={Dashboard} options={
{headerShown:false,
tabBarIcon:({color,size})=>(
<Icon name='home' color={color} size={30} />
)
}
}/>
<Tabs.Screen name='Products' component={ProductsStack} options={{
headerShown:false,
tabBarIcon:({color,size})=>(
<Icon name='microsoft-xbox-controller-view' color={color} size={30} />
)
}
}/>
<Tabs.Screen name='POS' component={POS} options={{
tabBarStyle:{display:'none'},
headerLeft: () => (
<TouchableOpacity onPress={() => {navigation.goBack()}}>
<Ionicons name='arrow-back-outline' size={25} color={'black'} style={{marginLeft:10}}/>
</TouchableOpacity>
),
tabBarLabel: () => null,
tabBarIcon:({color,size})=>{
return(
<View style={{
top:Platform.OS=="ios" ? -10:-20,
width:Platform.OS=="ios"?50:60,
height:Platform.OS=="ios"?50:60,
borderRadius:Platform.OS=="ios"?25:20,
backgroundColor:"#38BDF8",
alignItems:'center',
justifyContent:'center',
padding:5
}}>
<Icon name='point-of-sale' size={50} color={"white"} />
</View>
)
}
}
}/>
<Tabs.Screen name='Reports' component={Reports} options={
{
tabBarIcon:({color,size})=>(
<Icon name='chart-areaspline' color={color} size={30} />
)
}
}/>
<Tabs.Screen name='More' component={MoreStack} options={{
headerShown:false,
tabBarIcon:({color,size})=>(
<Icon name='view-grid-plus' color={color} size={30} />
)
}
}/>
</Tabs.Navigator>
)
}
export {MainStack}
我还利用 ProductStack 中的 useEffect 来消除第二个警告“错误警告:在渲染不同的组件 (ProductsStack) 时无法更新组件 (BottomTabNavigator)。要在 ProductsStack 中找到错误的 setState() 调用,请遵循堆栈跟踪如https://reactjs.org/link/setstate-in-render”中所述