React Native TypeScript开发遇ESLint嵌套组件不稳定警告求助
解决React Native中ESLint规则
react/no-unstable-nested-components警告 编写TypeScript React Native代码时触发了ESLint规则react/no-unstable-nested-components的警告,警告内容如下:
Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state
警告提示的解决方向:需将组件定义移出父组件“BottomTabNavigator”并通过props传递数据,或设置allowAsProps选项为true。
相关文件及代码
1. .eslintrc.js配置
module.exports = { root: true, extends: '@react-native', rules: { 'react-native/no-inline-styles': 0, }, };
2. 触发警告的代码片段
options={{ tabBarIcon: ({focused}: any) => { return ( <View style={{alignItems: 'center', justifyContent: 'center'}}> <Icon name={icon} style={{color: focused ? colors.green : colors.gray}} /> <Text style={{ fontSize: 12, color: focused ? colors.green : colors.gray, }}> {title} </Text> </View> ); }, }}
3. 完整的BottomTabNavigator代码
import React from 'react'; import {Text, View} from 'react-native'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import Icon from 'react-native-vector-icons/AntDesign'; import HomeScreen from '../screens/HomeScreen'; import CourseScreen from '../screens/CourseScreen'; import BlogScreen from '../screens/BlogScreen'; import SearchScreen from '../screens/SearchScreen'; import MenuScreen from '../screens/MenuScreen'; import {colors} from '../constants/colors'; const tabs = [ { title: 'Home', name: 'HomeScreen', screen: HomeScreen, icon: 'home', }, { title: 'Course', name: 'CourseScreen', screen: CourseScreen, icon: 'book', }, { title: 'Blog', name: 'BlogScreen', screen: BlogScreen, icon: 'edit', }, { title: 'Search', name: 'SearchScreen', screen: SearchScreen, icon: 'search1', }, { title: 'Menu', name: 'MenuScreen', screen: MenuScreen, icon: 'setting', }, ]; const Tab = createBottomTabNavigator(); const BottomTabNavigator = () => { return ( <Tab.Navigator initialRouteName="HomeScreen" screenOptions={{ headerShown: false, tabBarShowLabel: false, }}> {tabs.map(({title, name, screen, icon}: any, index: any) => { return ( <Tab.Screen key={index} name={name} component={screen} options={{ tabBarIcon: ({focused}: any) => { return ( <View style={{alignItems: 'center', justifyContent: 'center'}}> <Icon name={icon} style={{color: focused ? colors.green : colors.gray}} /> <Text style={{ fontSize: 12, color: focused ? colors.green : colors.gray, }}> {title} </Text> </View> ); }, }} /> ); })} </Tab.Navigator> ); }; export default BottomTabNavigator;
解决方案
方法一:提取嵌套组件为独立组件并传参
把tabBarIcon返回的UI结构提取成独立的函数组件,放在BottomTabNavigator外部定义,再通过props传入所需数据:
// 提取独立的TabBarIcon组件 const TabBarIcon = ({ focused, icon, title }: { focused: boolean; icon: string; title: string }) => { return ( <View style={{ alignItems: 'center', justifyContent: 'center' }}> <Icon name={icon} style={{ color: focused ? colors.green : colors.gray }} /> <Text style={{ fontSize: 12, color: focused ? colors.green : colors.gray, }}> {title} </Text> </View> ); }; const BottomTabNavigator = () => { return ( <Tab.Navigator initialRouteName="HomeScreen" screenOptions={{ headerShown: false, tabBarShowLabel: false, }}> {tabs.map(({ title, name, screen, icon }: any, index: any) => { return ( <Tab.Screen key={index} name={name} component={screen} options={{ tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} icon={icon} title={title} /> }} /> ); })} </Tab.Navigator> ); };
方法二:修改ESLint规则允许作为props传递
如果确认该场景不会引发性能问题,可以直接修改ESLint配置,开启allowAsProps选项:
module.exports = { root: true, extends: '@react-native', rules: { 'react-native/no-inline-styles': 0, 'react/no-unstable-nested-components': ['warn', { allowAsProps: true }] }, };
内容的提问来源于stack exchange,提问作者Khuong Viet Tai
相关产品推荐
相关产品推荐

