Redux Toolkit添加数据后返回页面报TypeError: property is not configurable问题排查
TypeError: property is not configurable 问题排查与解决
问题场景
使用Redux Toolkit创建userSlice,向cars数组添加条目后返回上一屏幕,触发如下错误:
TypeError: property is not configurable
This error is located at:
in VirtualizedList (created by FlatList)
...
相关代码
userSlice 代码
import { createSlice } from '@reduxjs/toolkit' const initialStateVal = { cars: [], } const userSlice = createSlice({ name: 'user', initialState: initialStateVal, reducers: { addNewCar: (state, action) => { state.cars.push(action.payload) //state.cars = [...state.cars, action.payload] }, deleteCar: (state, action) => { state.cars = state.cars.filter((car) => car.license !== action.payload) }, }, }) export const { addNewCar, deleteCar, } = userSlice.actions export default userSlice.reducer
添加条目调用代码
const addCar = () => { if (car.length > 0 && insurance.length > 0) { dispatch( addNewCar({ license: car, insurance: insurance, traffic: trafficChecked, osaKaskochecked: osaKaskochecked, täysKaskochecked: täysKaskochecked, }) ) setCar('') setInsurance('') setValid(true) navigation.goBack() carAddedToast() } else { setValid(false) } }
FlatList 展示代码
const cars = useSelector((state) => state.user.cars) {cars !== null ? <FlatList style={{ marginTop: 10 }} data={cars} keyExtractor={(item) => item.id} renderItem={({ item }) => { return ( <View style={licenseContainer}> <View style={{ flexDirection: 'column', justifyContent: 'center', width: editCars ? '20%' : '25%', }} > <Text style={{ color: colors.white, fontSize: 14, textAlign: 'left', }} > Rek.nro </Text> <Text key={item.license} style={carText}> {item.license} </Text> <View style={horizontalDivider} /> <Text style={{ color: colors.white, fontSize: 14, textAlign: 'left', }} > Vakuutus </Text> <Text key={item.insurance} style={carText}> {item.insurance} </Text> </View> <View style={{ flexDirection: 'column', justifyContent: 'center', width: editCars ? '24%' : '25%', }} > <Text style={{ color: colors.white, fontSize: 14, textAlign: 'center', }} > Liikenne </Text> <CheckBox center key={item.traffic} Component={TouchableWithoutFeedback} size={30} uncheckedColor={colors.white} checkedColor={colors.red} checked={item.traffic} /> </View> <View style={{ flexDirection: 'column', justifyContent: 'center', width: editCars ? '24%' : '25%', }} > <Text style={{ color: colors.white, fontSize: 14, textAlign: 'center', }} > Osakasko </Text> <CheckBox center key={item.osaKaskochecked} Component={TouchableWithoutFeedback} size={30} uncheckedColor={colors.white} checkedColor={colors.red} checked={item.osaKaskochecked} /> </View> <View style={{ flexDirection: 'column', justifyContent: 'center', width: editCars ? '24%' : '25%', }} > <Text style={{ color: colors.white, fontSize: 14, textAlign: 'center', }} > Täyskasko </Text> <CheckBox center key={item.täysKaskochecked} Component={TouchableWithoutFeedback} size={30} uncheckedColor={colors.white} checkedColor={colors.red} checked={item.täysKaskochecked} /> </View> {editCars ? ( <View style={{ flexDirection: 'column', justifyContent: 'center', width: editCars ? '10%' : null, }} > <Ionicons name='ios-close-circle-outline' size={30} color={colors.black} style={removeIcon} onPress={() => removeCar(item.license)} /> </View> ) : null} </View> ) }} ItemSeparatorComponent={() => { return <View style={divider} /> }} /> : null}
用户已尝试的方案
- 两种数组更新方式:
state.cars.push(action.payload)和state.cars = [...state.cars, action.payload] - 添加空检查
cars !== null
均未解决问题。
问题原因
- FlatList keyExtractor 无效:设置了
keyExtractor={(item) => item.id},但添加的每个car对象根本没有id属性,导致所有item的key都是undefined。FlatList依赖唯一key管理列表项渲染,无效key会引发内部DOM更新时的配置错误。 - 组件内key滥用:renderItem中给Text、CheckBox设置的key使用了布尔值(如
item.traffic)或非唯一字符串(如item.license),React要求key必须是稳定且唯一的字符串/数字,重复或不稳定的key会导致React无法正确追踪组件变化,触发property is not configurable错误。
解决方案
1. 给每个car添加唯一id,修复keyExtractor
在添加car时生成唯一标识(比如时间戳),确保keyExtractor能获取有效key:
// 修改addCar中的dispatch参数 dispatch( addNewCar({ id: Date.now().toString(), // 生成唯一id license: car, insurance: insurance, traffic: trafficChecked, osaKaskochecked: osaKaskochecked, täysKaskochecked: täysKaskochecked, }) )
此时keyExtractor={(item) => item.id}就能正常工作。
2. 移除或修正组件内的无效key
renderItem内部的Text、CheckBox不需要单独设置key(FlatList的key已经管理了父容器的唯一性),如果一定要加,必须用结合item.id的唯一值:
- 错误示例:
<Text key={item.license} style={carText}>{item.license}</Text> <CheckBox key={item.traffic} checked={item.traffic} />
- 正确做法:移除这些key,或者改为:
<Text key={`${item.id}-license`} style={carText}>{item.license}</Text> <CheckBox key={`${item.id}-traffic`} checked={item.traffic} />
3. 可选:规范Redux状态更新(非必要)
虽然RTK的Immer已经处理了不可变性,直接push没问题,但如果想更符合不可变更新规范,可以继续使用:
addNewCar: (state, action) => { state.cars = [...state.cars, action.payload] }
这不是当前错误的根源,但能保持代码风格一致。
内容的提问来源于stack exchange,提问作者Jukka Koivu
相关产品推荐
相关产品推荐

