我有嵌套的商品目录 . 它有一些类别,可以引导您到另一个类别和类别,这些类别和类别会引导您使用该组的商品页面进行分页 . 我不知道它是如何完成的,我决定做以下事情 . 当用户点击最终类别(跟随一组商品)时,我将他导航到组件 **** . 它显示任何类别ID的商品列表 . 此组件连接到redux存储 . 它仅从redux商店获取所有数据 . 我有一个单独的货物减速机 . 这个reducer ' initial state is null when you start app the first time. I don't想要将整个目录预加载到商店,我想部分地做 . 点击商品类别后,用户会重定向到具有类别ID参数的GoodsList组件 . 然后GoodsList从这个特定类别的远程服务器商品列表下载(如果它还没有存储,除此之外的所有商品卡将根据下载的数据显示)并且当组件连接到商店(并且数据是已更新的组件已重新显示,并显示了货物清单 . 问题是,第一个第一次组件呈现的商品集是空的,然后在其构造函数中更新数据 - >组件重新呈现,然后我才能获得我可以在屏幕上显示的数据集 . 当用户点击特定类别但是在显示货物的组件被挂载之前,我该如何部分填充redux商店(商品)?我可以在加载数据时显示微调器,但为什么我需要渲染两次组件 . 或者......还有其他想法吗?

Update. If the question above is hard to understand, see info below.

CatalogComponent.js

/* necessary imports */
import categories from 'appcontent/categories'; // initial categories

const CatalogComponent = () => {

    return (
        <ScrollView>
        <View style={styles.container}>

                // If there is no passed categories for current component, using base set of categories (the whole catalog).
                // ReactNavigation is used. Navigation prop is from there.
                <CatalogList categories={!!props.navigation.state.params ? props.navigation.state.params.categories : categories}/>

        </View>
        </ScrollView>
    )

}

categories.js

const goods = [
    {
        "id": 1,
        "title": "First cat",
        "subs": [
            {
                "id": 11,
                "title": "First subcat",
                "subs": [
                    {
                        "id": 111,
                        "title": "first final cat",
                        "subs": null
                    },
                    {
                        "id": 112,
                        "title": "first final cat",
                        "subs": null
                    },
                ],
            },
        ],

    },
    {
        "id": 2,
        "title": "Second cat",
        "subs": null
    },
]

export default goods;

CatalogList.js

const CatalogList = (props) => {

    const { categories } = props;

    return (

        <View>

            {

                // Render each element of current catalog level and passin
                categories.map((item) => {
                    return <CatalogItem key={item.title} categories={item} />
                })
            }


        </View>


    );
}

CatalogItem.js

const onPress = (item, navigation) => {

    navigation.navigate({
        routeName: 'CatalogComponent',
        params: { categories: item.subs, title: item.title }, // this categories is props.navigation.state.params.categories in CatalogComponent
        key: Math.random() * 10000 // needed for I could open the same Route with new paarmeters
    })

};

const CatalogItem = (props) => {

    const { id, title, subs } = props.categories;

    return (

        <TouchableOpacity
            onPress={() => {

                if (props.categories.subs !== null && props.categories.subs.length > 0) {
                    // Redirect to the very first route (component) CatalogComponent with new categories parameter (child catalog list for current category)
                    onPress(props.categories, props.navigation); // props.navigation is for redirect purposes using ReactNavigation
                } else {
                    // Show the list of goods for category of ID equals id
                    // THE MAIN PART OF QUESTION STARTS FROM HERE
                    props.navigation.navigate({
                        routeName: 'GoodsList',
                        params: { categoryId: 123 },
                    })
                }

                //props.categories.subs !== null && props.categories.subs.length>0 && onPress(props.categories, props.navigation)
            }}
        >
            <View style={styles.container}>

                <Text style={styles.text}>{title}</Text>
                <Icon style={styles.arrow} name="chevron-right" size={20} color="gray" />

            </View>
        </TouchableOpacity>


    );
}

GoodsList.js

/* Necesary imports */
import goodsList from 'appcontent/goods';

class GoodsList extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            loading: true
        }

    }

    componentWillUnmount() {
        clearTimeout();
    }

    componentWillMount() {

        // Setting of category to state
        this.catId = this.props.navigation.state.params.categoryId;

        // Imitate fetching data from remote server by setting timeout
        setTimeout(() => {

            // "Fetching" data
            this.goods = goodsList[this.catId];

            // The first thing I do is save data to Redux store. Render method below gets data from Redux.
            this.props.dispatch(goodsFill({ goods: this.goods, catId: this.catId })); // the reducer code is below
            this.setState((curState) => {
                return {
                    ...curState,
                    loading: 0
                }
            });
        }, 5000);

    }


    render() {

        const { goods } = this.props;

        console.log('settingGoodsList', goods.goods); // !!!

        return (

            <View style={styles.container}>

                {
                    this.state.loading && <Text>Loading</Text>
                }

                {

                    goods.goods[this.catId] && goods.goods[this.catId].map((item, index) => {
                        console.log(item);
                        return <Text key={item[Object.keys(item)[0]].name}>{item[Object.keys(item)[0]].name}</Text>
                    })

                }


            </View>


        );
    }

}

减速器

const initReducerDefaultState = {
    goods: {}
};

export default (state = initReducerDefaultState, action) => {

    switch (action.type) {
        case 'GOODS_FILL':
            return {
                ...state, goods: { ...state.goods, [action.catId]: action.goods }
            }
        default:
            return state;
    }
}

行动顺序 . 您输入目录页面CatalogComponent . 你第一次看到整个目录(它的顶级类别) . 单击某些项目后,您将使用其子类别等进入下一级别 . 从技术上讲,您将重定向到相同的路径,但这次使用的是从之前传递的类别 . 如果该类别是最终的(它没有子类别,它应该跟随您到其商品列表) . 但是,当首次打开具有特定categoryId的GoodsList时,我想获取数据(此类别的商品)并首先将其保存到redux存储(仅当此类别没有数据时,代码中没有这样的检查,但我'将它包括在内) . 只有在该组件从Redux(不是直接从远程服务器)获取数据并呈现它之后 . 同时我向用户展示微调器 .

在GoodsList中,您可以看到console.log('settingGoodsList',goods.goods);问题是它叫了两次 . 第一次 - 渲染组件时 . 第二次 - 获取数据,更改存储,并自动重新呈现组件.js这是一个问题,这是获取远程数据工作的方式还是我做错了什么?我首先应该获取数据,然后组件应该呈现其内容 . 我认为componentWillMount()是可以帮助我的地方 . 它在渲染功能之前调用 . 但是console.log()输出两次信息 .