property is not configurable 报错?
来源:21-1 实战仿写小红书App-搭建首页框架

西瓜一号
2024-08-02
shop.tsx
import React, { useCallback, useEffect } from "react";
import { View, Text, StyleSheet, Dimensions, TextInput, Image, FlatList,TouchableOpacity } from "react-native";
import { useLocalObservable } from 'mobx-react-lite';
import { observer } from 'mobx-react';
import { useNavigation } from "@react-navigation/native";
import { StackNavigationProp } from "@react-navigation/stack";
import ShopStore from "./ShopStore";
import icon_search from '../../assets/icon_search.png'
import icon_shop_car from '../../assets/icon_shop_car.png'
import icon_orders from '../../assets/icon_orders.png'
import icon_menu_more from '../../assets/icon_menu_more.png'
import itemImg from '../../public/goods/goods03/img_01.jpg'
import categoryImg from '../../public/goods/top10/top1.jpg'
const { width: SCREEN_WIDTH } = Dimensions.get('window');
const ITEM_WIDTH = SCREEN_WIDTH - 18 >> 1;
export default observer(() => {
const navigate = useNavigation<StackNavigationProp<any>>();
const store = useLocalObservable(() => new ShopStore());
useEffect(() => {
store.requestGoodsList();
store.requestTop10Category();
}, []);
const onSearchPress = ()=>{
navigate.push('ShopSearchPage')
}
const renderTitleView = () => {
const s = StyleSheet.create({
root: {
width: '100%',
height: 48,
borderBottomColor: '#eee',
borderBottomWidth: StyleSheet.hairlineWidth,
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 16,
},
inputView: {
flex: 1,
flexDirection: 'row',
backgroundColor: '#f0f0f0',
borderRadius: 20,
height: 40,
alignItems: 'center',
paddingHorizontal: 12,
marginRight: 4,
},
editImg: {
width: 24,
height: 24,
resizeMode: 'contain',
// backgroundColor:'green',
tintColor: '#333',
},
input: {
height: '100%',
flex: 1,
paddingVertical: 0,
color: '#333',
textAlignVertical: 'center',
// backgroundColor:'yellow',
},
iconImg: {
marginHorizontal: 4,
width: 26,
height: 26,
resizeMode: 'contain',
},
});
return (
<View style={s.root}>
<TouchableOpacity style={s.inputView} onPress={onSearchPress}>
<Image style={s.editImg} source={icon_search} />
<Text style={s.input}>bm吊带</Text>
{/* <TextInput
style={s.input}
placeholder="bm吊带"
placeholderTextColor='#999'
/> */}
</TouchableOpacity>
<Image style={s.iconImg} source={icon_shop_car} />
<Image style={s.iconImg} source={icon_orders} />
<Image style={s.iconImg} source={icon_menu_more} />
</View>
);
};
const renderItem = ({ item, index }: { item: GoodsSimple, index: number }) => {
const s = StyleSheet.create({
root: {
width: ITEM_WIDTH,
borderRadius: 8,
overflow: 'hidden',
// backgroundColor:'green',
marginLeft: 6,
marginBottom: 6,
},
img: {
width: '100%',
height: 200,
resizeMode: 'cover',
},
titleTxt: {
width: '100%',
fontSize: 12,
color: '#333',
marginTop: 6,
},
promotion:{
width:100,
fontSize:14,
color:'#999',
borderWidth:1,
borderColor:'#bbb',
borderRadius:2,
textAlign:'center',
paddingHorizontal:8,
marginTop:4,
},
prefix:{
fontSize: 14,
color: '#333',
fontWeight:'bold',
},
priceTxt: {
fontSize: 20,
color: '#333',
fontWeight:'bold',
textAlign:'justify',
marginTop:4,
},
originPriceTxt:{
fontSize: 14,
color: '#666',
fontWeight:'normal',
},
});
return (
<View style={s.root}>
{/* <Image style={s.img} source={{ uri: item.image }} /> */}
<Image style={s.img} source={itemImg} />
<Text style={s.titleTxt}>{item.title}</Text>
{!!item.promotion && <Text style={s.promotion}>{item.promotion}</Text>}
<Text style={s.prefix}>
¥<Text style={s.priceTxt}> {item.price}
{!!item.originPrice && <Text style={s.originPriceTxt}> 原价:{item.originPrice}</Text>}
</Text>
</Text>
</View>
);
}
const HeadCategory = ()=>{
const { categoryList } = store;
const s = StyleSheet.create({
root:{
width:'100%',
flexDirection:'row',
flexWrap:'wrap',
marginBottom:12,
},
item:{
alignItems:'center',
width:'20%',
// paddingHorizontal:8,
// backgroundColor:'red',
},
img:{
width:40,
height:40,
resizeMode:'contain',
},
txt:{
width:'100%',
fontSize:14,
color:'#333',
marginTop:6,
// backgroundColor:'pink',
textAlign:'center',
},
});
return(
<View style={s.root}>
{
categoryList.map((item,index) => {
return(
<View style={s.item} key={`${item.id} -${index}`}>
{/* <Image style={s.img} source={{uri:item.image}}/> */}
<Image style={s.img} source={categoryImg}/>
<Text style={s.txt}>{item.name}</Text>
</View>
);
})
}
</View>
);
};
console.log('aaaa' + JSON.stringify(store.goodsList));
return (
<View style={s.root}>
{renderTitleView()}
<FlatList
style={s.flatList}
data={store.goodsList}
keyExtractor={item=>`${item.id}`}
extraData={[store.categoryList]}
renderItem={renderItem}
numColumns={2}
ListHeaderComponent={<HeadCategory/>}
>
</FlatList>
</View>
);
});
const s = StyleSheet.create({
root: {
width: '100%',
height: '100%',
backgroundColor: 'white',
},
flatList: {
flex: 1,
},
});
shopStore.ts
import { observable, runInAction } from "mobx";
import apiConfig from "../../api/Apis";
import { request } from "../../utils/request"
import { makeAutoObservable } from 'mobx';
import Loading from "../../components/widget/Loading";
const SIZE = 10;
export default class ShopStore {
page: number = 1;
@observable goodsList: GoodsSimple[] = []; //@observable 装饰器,homeList变化会引起UI刷新的
@observable categoryList: GoodsCategory[] = [];
@observable refreshing: boolean = false;
constructor() {
makeAutoObservable(this);
}
setPage = () => {
this.page = 1;
}
requestGoodsList = async () => {
if (this.refreshing === true) {
return; //正在请求,不可以再次请求
}
Loading.show();
try {
runInAction(() => {
this.refreshing = true;
})
const params = {
page: this.page,
size: SIZE,
};
const { data } = await request(apiConfig.goodsList.name, params);
console.log(apiConfig.goodsList.name);
console.log(data);
if (data?.length) {
// 有数据
if (this.page === 1) {
runInAction(() => {
this.goodsList = data;
})
} else {
runInAction(() => {
this.goodsList = [...this.goodsList, ...data];
})
}
runInAction(() => {
this.page = this.page + 1;
})
} else {
//无数据
if (this.page === 1) {
runInAction(() => {
this.goodsList = [];
})
} else {
//已经加载完了,没有新数据了
console.log('已经加载完了,没有新数据了');
}
}
} catch (error) {
console.error(error);
} finally {
runInAction(() => {
this.refreshing = false;
});
Loading.hide();
}
};
requestTop10Category = async () => {
try {
runInAction(() => {
this.refreshing = true;
})
const { data } = await request(apiConfig.top10Category.name, {});
console.log(apiConfig.top10Category.name);
console.log(data);
// 有数据
runInAction(() => {
this.categoryList = data || [];
})
} catch (error) {
console.error(error);
}
};
}
经过多次测试,确认是flatList组件引起的报错,注释掉就不报错了
shop,home ,message页面都报同样的错,这3个页面都有flatlist(单独注释flatlist就不报错了)
mine页面不报错,mine没有flatlist
调试方法
1、data写死数据也报错
2、单独注释一些属性,还是报错,没找到引起这个的原因属性
麻烦老师看下是什么问题
网上说是TS和装饰器语法兼容性问题,或者需要babel配置什么?
写回答
1回答
-
FE大公爵
2025-04-22
看了你的代码,没发现明显的问题。组件属性和style属性都还正常。你这样调试,FlatList一共两个部分,一个HeadCategory,一个renderItem,你把这两个地方全改成空组件,就写一个View,如果不报错再把元素一个一个加进去,看最后是哪个元素报错。
00
相似问题