React Native使用uuidv4渲染多组件时触发TypeError错误
问题描述
我想实现点击“Add Lift”按钮后渲染多个自定义<Lift/>组件,但点击几次按钮后出现错误。改用普通数字作为ID时代码能正常运行,用uuidv4就报错,希望解决这个问题。
相关代码
import "react-native-get-random-values"; import { StyleSheet, TextInput, View, Text, TouchableHighlight, Button } from 'react-native'; import React, { useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import Lift from './Lift' export default function Lifts() { // const [cards, setCards] = useState([{ id: uuidv4() }]) // const onPress = () => setCards([...cards, [{ id: uuidv4() }]]) const [cards, setCards] = useState([uuidv4()]) const onPress = () => setCards([...cards, uuidv4()]) const liftCards = cards.map((id) => { return ( <View key={id}> <Lift /> </View> ) }) return ( <View> <TouchableHighlight onPress={onPress} underlayColor={'#DDDDDD'} style={styles.touchable}> <View style={styles.button}> <Text> Add Lift </Text> </View> </TouchableHighlight> {/* <Text style={{ alignSelf: 'center', top: 100 }}> {cards} </Text> */} { cards.map((data, id) => { return ( <Text> {id} </Text> ) }) } </View> ) } const styles = StyleSheet.create({ button: { alignItems: 'center', borderWidth: 2, borderColor: 'black', borderRadius: 10, padding: 10, }, touchable: { marginHorizontal: 10, top: 10 } })
错误信息
ERROR TypeError: undefined is not a function This error is located at: in Lifts (created by SceneView) in StaticContainer in EnsureSingleNavigator (created by SceneView) in SceneView (created by SceneView) in RCTView (created by View) in View (created by DebugContainer) in DebugContainer (created by MaybeNestedStack) in MaybeNestedStack (created by SceneView) in RCTView (created by View) in View (created by SceneView) in RNSScreen (created by AnimatedComponent) in AnimatedComponent in AnimatedComponentWrapper (created by InnerScreen) in Suspender (created by Freeze) in Suspense (created by Freeze) in Freeze (created by DelayedFreeze) in DelayedFreeze (created by InnerScreen) in InnerScreen (created by Screen) in Screen (created by SceneView) in SceneView (created by NativeStackViewInner) in Suspender (created by Freeze) in Suspense (created by Freeze) in Freeze (created by DelayedFreeze) in DelayedFreeze (created by ScreenStack) in RNSScreenStack (created by ScreenStack) in ScreenStack (created by NativeStackViewInner) in NativeStackViewInner (created by NativeStackView) in RNCSafeAreaProvider (created by SafeAreaProvider) in SafeAreaProvider (created by SafeAreaInsetsContext) in SafeAreaProviderCompat (created by NativeStackView) in NativeStackView (created by NativeStackNavigator) in PreventRemoveProvider (created by NavigationContent) in NavigationContent in Unknown (created by NativeStackNavigator) in NativeStackNavigator (created by App) in EnsureSingleNavigator in BaseNavigationContainer in ThemeProvider in NavigationContainerInner (created by App) in App (created by withDevTools(App)) in withDevTools(App) in RCTView (created by View) in View (created by AppContainer) in RCTView (created by View) in View (created by AppContainer) in AppContainer in main(RootComponent), js engine: hermes
排查情况
- 改用普通数字作为ID时,代码正常运行,
cards数组长度能正确递增 - 确定问题出在
uuidv4的使用上
解决方案
问题出在React Native环境下uuid库的v4生成逻辑依赖的随机数初始化时机不对,或者库的适配问题,给你两个可行的解决办法:
办法一:调整react-native-get-random-values的导入位置
uuid的v4需要依赖全局的随机数支持,你现在只在组件里导入react-native-get-random-values,可能初始化时机太晚。
- 先确认依赖都已安装:
npm install uuid react-native-get-random-values
- 把
import 'react-native-get-random-values';移到项目的入口文件(比如index.js或者App.js的最顶部),确保在任何其他代码之前加载。 - 组件里的代码不用改,保持原来的
uuidv4()调用即可。
办法二:换用React Native专属的UUID库
如果上面的办法没用,直接用react-native-uuid更省心:
- 安装依赖:
npm install react-native-uuid
- 替换组件里的导入和生成逻辑:
// 替换原来的uuid导入 import uuid from 'react-native-uuid'; // 修改state和onPress逻辑 const [cards, setCards] = useState([uuid.v4()]) const onPress = () => setCards([...cards, uuid.v4()])
额外提醒
你代码里定义了liftCards但没渲染,要在return的JSX里加上{liftCards}才能看到<Lift/>组件。
内容的提问来源于stack exchange,提问作者Ani Sr.
相关产品推荐
相关产品推荐

