RN升级至0.71.3后使用Array.map出现渲染错误求助
React Native 0.71.3升级后页面渲染错误问题
问题描述
应用原本基于React Native 0.70.4正常运行,升级至0.71.3后,两个页面出现渲染异常:
- Android端错误:
Attempting to change configurable attribute of unconfigurable property - iOS端错误:
the property is not configurable
场景与代码示例
页面通过Axios从后端获取菜谱数据,请求代码如下:
const fetchOneRecipe = () => { axiosInstance .get(getUrl()) .then((res) => { setMyRecipe(res.data); setLoading(false); }) .catch((err) => { setLoading(false); console.log("error one recipe: ", err); }); };
展示菜谱子属性(如食材、分类)时,使用Array.map遍历渲染:
{Object.values(myRecipe?.relatedTraits).map((trait) => { return trait.traitSetCode === "COURSES" || trait.traitSetCode === "PREPARATION_METHODS" || trait.traitSetCode === "MAIN_INGREDIENTS" ? ( <View> <Text style={Styles.h4Black60}> {trait.name} {" "} </Text> </View> ) : null; })}
触发条件
仅当同时使用上述两段代码时才会报错:
- 移除所有
Array.map代码,页面无错误但无法展示对应数据 - 不使用
Array.map的其他菜谱数据可正常展示
排查情况
- 单独使用Axios或单独使用
Array.map的页面均正常工作 - 改用
Array.forEach仍出现相同错误 - 回滚RN版本至0.70.4后,问题消失
更新信息
1. 最小化页面代码后仍报错
简化后的核心页面代码如下:
import React, { useState, useEffect } from "react"; import { View, Text, SafeAreaView, ScrollView, } from "react-native"; import Styles from "../../Styles/Styles"; import SousHeader from "../../Components/SousHeader"; import { oneRecipe } from "../../interface/interface"; import { axiosInstance } from "../../API/API"; import { useRoute } from "@react-navigation/native"; import urls from "../../Services/Services"; import { useSelector } from "react-redux"; import Spinner from "../../Components/Spinner"; const RecipeViewScreen = () => { const route: any = useRoute(); const recipeId: number = route.params?.recipeID; const [loading, setLoading] = useState<boolean>(true); const [myRecipe, setMyRecipe] = useState<oneRecipe>(); const [versionId] = useState<number>(recipeId); const language = useSelector((state: any) => state.language.language); useEffect(() => { fetchOneRecipe(); }, []); const fetchOneRecipe = () => { axiosInstance .get(getUrl()) .then((res) => { setMyRecipe(res.data); setLoading(false); }) .catch((err) => { setLoading(false); console.log("error one recipe: ", err); }); }; let getUrl = (): string => { //Original URL //let text = `${urls.oneRecipe(versionId, language)}`; let text = "https://jsonplaceholder.typicode.com/todos"; return text; }; //Return false const isHermes = () => !!global.HermesInternal; console.log(isHermes()); return ( <SafeAreaView> <View style={Styles.container}> <SousHeader title={myRecipe?.name} /> <ScrollView> {loading ? ( <Spinner /> ) : ( <> {myRecipe !== undefined && ( <> <> {/* Original text */} {/*{Object.values(myRecipe?.relatedTraits).map((trait) => {*/} {/* return trait.traitSetCode === "COURSES" ||*/} {/* trait.traitSetCode === "PREPARATION_METHODS" ||*/} {/* trait.traitSetCode === "MAIN_INGREDIENTS" ? (*/} {/* <View>*/} {/* <Text style={Styles.h4Black60}>*/} {/* {trait.name}*/} {/* {" "}*/} {/* </Text>*/} {/* </View>*/} {/* ) : null;*/} {/*})}*/} {Object.values(myRecipe).map((trait) => { return trait.id === 2 || trait.id === 4 || trait.id === 6 ? ( <View> <Text> {trait.title} {" "} </Text> </View> ) : null; })} </> </> )} </> )} </ScrollView> </View> </SafeAreaView> ); }; export default RecipeViewScreen;
2. 热重载后错误消失
模拟器触发错误后,修改页面代码并保存,页面重载后错误不再出现。
3. 导航方式影响错误触发
- 将故障页面设为Stack.navigator的根页面时,页面可正常运行
- 通过
navigation.navigate或navigation.dispatch导航至该页面时,仍会报错
导航配置代码:
return ( <Stack.Navigator> <Stack.Screen name="recipeview" component={RecipeViewScreen} /> </Stack.Navigator> );
跳转触发代码:
<Text onPress={() => navigation.navigate('recipeview' as never) } > Test </Text>
项目package.json配置
{ "name": "sfw", "version": "0.1.40", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", "start": "react-native start", "test": "jest" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "6.3.0", "@fortawesome/free-solid-svg-icons": "6.3.0", "@fortawesome/react-native-fontawesome": "0.3.0", "@react-native-async-storage/async-storage": "1.17.11", "@react-native-community/checkbox": "0.5.14", "@react-native-community/cli-platform-ios": "10.2.0", "@react-native-community/datetimepicker": "6.7.5", "@react-native-google-signin/google-signin": "9.0.2", "@react-native-picker/picker": "2.4.8", "@react-navigation/drawer": "6.6.2", "@react-navigation/native": "6.1.6", "@react-navigation/stack": "6.3.16", "@reduxjs/toolkit": "1.9.3", "@rneui/themed": "4.0.0-rc.7", "@types/react-native-version-check": "3.4.5", "axios": "1.3.4", "formik": "2.2.9", "moment": "2.29.4", "react": "18.2.0", "react-native": "0.71.3", "react-native-collapsible-tab-view": "6.0.1", "react-native-element-dropdown": "2.8.0", "react-native-fbsdk-next": "11.1.0", "react-native-gesture-handler": "^2.9.0", "react-native-gradle-plugin": "0.71.16", "react-native-image-viewing": "0.2.2", "react-native-localize": "2.2.5", "react-native-modal": "13.0.1", "react-native-modal-datetime-picker": "14.0.1", "react-native-pager-view": "^6.1.4", "react-native-paper": "5.3.1", "react-native-reanimated": "^3.0.2", "react-native-render-html": "6.3.4", "react-native-safe-area-context": "^4.5.0", "react-native-screens": "^3.20.0", "react-native-splash-screen": "3.3.0", "react-native-svg": "^13.8.0", "react-native-vector-icons": "9.2.0", "react-native-version-check": "3.4.7", "react-native-webview": "11.26.1", "react-redux": "8.0.5", "redux": "4.2.1", "redux-persist": "6.0.0", "yup": "0.32.11" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.5", "@react-native-community/eslint-config": "^3.2.0", "@tsconfig/react-native": "^2.0.2", "@types/jest": "^29.2.1", "@types/react": "^18.0.24", "@types/react-native-fbsdk": "^3.0.2", "@types/react-native-vector-icons": "^6.4.10", "@types/react-test-renderer": "^18.0.0", "babel-jest": "^29.2.1", "eslint": "^8.19.0", "jest": "^29.2.1", "metro-react-native-babel-preset": "^0.73.7", "mocha": "^10.1.0", "prettier": "^2.4.1", "react-test-renderer": "18.2.0", "typescript": "^4.8.4" }, "resolutions": { "@types/react": "^17", "react-devtools-core": "4.14.0" }, "jest": { "preset": "react-native", "moduleFileExtensions": [ "ts", "tsx", "js", "jsx", "json", "node" ] }, "main": "index.js", "license": "MIT" }
内容的提问来源于stack exchange,提问作者VCrete
相关产品推荐
相关产品推荐

