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,如果不报错再把元素一个一个加进去,看最后是哪个元素报错。

0
0

RN从0到1系统精讲与小红书APP实战

30+小案例+2个实战项目,快人一步提升个职业竞争力

295 学习 · 211 问题

查看课程