【问题标题】:React Native Redux - Why can't I access data in my redux store and display it?React Native Redux - 为什么我不能访问我的 redux 存储中的数据并显示它?
【发布时间】:2021-04-17 03:00:25
【问题描述】:

我在 Coursera 上完成了 React Native 课程,并拥有一个使用 redux 和 json-server 来显示数据的工作应用程序。我现在正在制作自己的应用程序,当我尝试访问它时,我遇到了很多问题,redux 不显示我的数据。

在尝试自己找出问题后,我最终只是从我以前的项目中复制了所有 redux 文件并将其配置为工作。在将它们全部编辑以显示我当前的数据后,我又开始遇到问题,我不小心删除了工作代码的 git commit 并恢复到复制所有文件后的状态。我不能再让我的flatlisthomecomponent 中显示任何数据。

我已将代码压缩成最简单的形式,希望能得到一些帮助。

我基本上只是尝试使用 FlatList 来使用 MapStateToProps 显示来自我的 redux 存储的数据。在当前状态下,该列表根本没有显示,这对我来说意味着它没有数据可以显示。它肯定在不同的迭代中工作,并显示了我的 db.json 文件中的数据。我不确定为什么它现在不起作用。

HomeComponent.js

import React, { Component } from 'react';
import { View, Image, FlatList} from 'react-native';
import { ListItem } from 'react-native-elements';
import { connect } from 'react-redux';
import { baseUrl } from '../shared/baseUrl';

const mapStateToProps = state => {
    return{
        dishes: state.dishes
    }
}

class HomeScreen extends Component {
    render() {

        const renderCategory = ({item, index}) => {
            return (
                <ListItem
                    key={index}
                    title={item.name}
                    subtitle={item.description}
                    hideChevron={true}
                    leftAvatar={{ source: { uri: baseUrl}}}
                    />
            );
        }
        return (
            <View>
                <Image
                    source = {{ uri: baseUrl + 'images/ezywhip.png'}}
                    style={{width:200, height: 200}}
                />
                <FlatList 
                    data={this.props.dishes.dishes}
                    renderItem={renderCategory}
                    keyExtractor={item => item.id.toString()}
                />
            </View>

        );
    }
}

export default connect(mapStateToProps)(HomeScreen);

ActionCreator.js

import * as ActionTypes from './ActionTypes';
import { baseUrl } from '../shared/baseUrl';


export const fetchDishes = () => (dispatch) => {
    
    dispatch(dishesLoading());

    return fetch(baseUrl + 'dishes')
    .then(response => {
        if (response.ok) {
            return response;
        } else {
            var error = new Error('Error ' + response.status + ': ' + response.statusText);
            error.response = response; 
            throw error;
        }
    },
    error => {
        var errmess = new Error(error.message);
        throw errmess;
    })
    .then(response => response.json())
    .then(dishes => dispatch(addDishes(dishes)))
    .catch(error => dispatch(dishesFailed(error.message)));
};

export const dishesLoading = () => ({
    type: ActionTypes.DISHES_LOADING
});

export const dishesFailed = (errmess) => ({
    type: ActionTypes.DISHES_FAILED,
    payload: errmess
});

export const addDishes = (dishes) => ({
    type: ActionTypes.ADD_DISHES,
    payload: dishes
});

ActionTypes.js

export const DISHES_LOADING = 'DISHES_LOADING';
export const ADD_DISHES = 'ADD_DISHES';
export const DISHES_FAILED = 'DISHES_FAILED';

ConfigureStore.js

import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import { dishes } from './dishes';

export const ConfigureStore = () => {
    const store = createStore(dishes,
        applyMiddleware(thunk, logger)
    );

    return store;
}

dishes.js

import * as ActionTypes from './ActionTypes';

export const dishes = (
    state = {
        isLoading: true,
        errMess: null,
        dishes: []
    },
    action) => {
        switch(action.type) {
            case ActionTypes.ADD_DISHES:
                return{...state, isLoading: false, errMess: null, dishes: action.payload};

            case ActionTypes.DISHES_LOADING:
                return{...state, isLoading: true, errMess: null, dishes: []};

            case ActionTypes.DISHES_FAILED:
                return{...state, isLoading: false, errMess: action.payload};

            default:
                return state;
        }
    }

MainComponent.js

import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import AccountScreen from './AccountComponent';
import CartScreen from './CartComponent';
import DetailScreen from './DetailsComponent';
import HomeScreen from './HomeComponent';
import MenuScreen from './MenuComponent';
import OrderScreen from './OrderComponent';
import SearchScreen from './SearchComponent';

import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer, StackActions } from '@react-navigation/native';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';

import { connect } from 'react-redux';
import { fetchDishes } from '../redux/ActionCreators';

const mapStateToProps = state => {
    return {
        dishes: state.dishes
    }
}

const mapDispatchToProps = dispatch => ({
    fetchDishes: () => dispatch(fetchDishes())
})

const Stack = createStackNavigator();
const TabStack = createMaterialBottomTabNavigator();

class Main extends Component {
    componentDidMount() {
        this.props.fetchDishes();
    }

    homeStack = () =>
        <Stack.Navigator>
            <Stack.Screen
                name="Home"
                component={HomeScreen}
                options={{
                    headerShown: false,
                }}
            />
            <Stack.Screen
                name="Menu"
                component={MenuScreen}
            />
            <Stack.Screen
                name="Details"
                component={DetailScreen}
            />
        </Stack.Navigator>
    
    homeTabStack = () =>    
        <TabStack.Navigator
            activeColor="#f0edf6"
            inactiveColor="#3e2465"
            barStyle={{ backgroundColor: '#ff69b4' }}>
            <TabStack.Screen
                name="Home"
                component={this.homeStack}
            />
            <TabStack.Screen
                name="Search"
                component={SearchScreen}
            />
            <TabStack.Screen
                name="Cart"
                component={CartScreen}
            />
            <TabStack.Screen
                name="Order"
                component={OrderScreen}
            />
            <TabStack.Screen
                name="Account"
                component={AccountScreen}
            />
        </TabStack.Navigator>
    

    render() {
        return (
            <NavigationContainer>
                <Stack.Navigator 
                    initialRouteName="Home"y >
                    <Stack.Screen 
                    name="Home" 
                    component={this.homeTabStack}
                    options={{
                        headerShown: true,
                        headerTitleAlign: 'center'
                    }}
                    />
                </Stack.Navigator>
            </NavigationContainer>
        )
    }
}

  export default connect(mapStateToProps, mapDispatchToProps)(Main);

db.json

{
    "dishes": [{
            "id": 0,
            "name": "Dish 1",
            "category": "Products",
            "label": "",
            "featured": true,
            "description": "Dish 1"
        },
        {
            "id": 1,
            "name": "Dish 2",
            "category": "Products",
            "label": "",
            "featured": false,
            "description": "Dish 2"
        },
        {
            "id": 2,
            "name": "Dish 3",
            "category": "Products",
            "label": "",
            "featured": false,
            "description": "Dish 3"
        }
    ]
}

【问题讨论】:

    标签: reactjs react-native redux react-redux mapstatetoprops


    【解决方案1】:

    我认为因为dishes 你的“根”减速器state @ 987654323@减速器状态对象。换句话说,当您将HomeScreen 连接到您的商店时,您只需要state.dishes 即可访问该数组,state.dishes.dishes 是未定义的。

    class HomeScreen extends Component {
      render() {
        const renderCategory = ({ item, index }) => {
          return (
            <ListItem
              key={index}
              title={item.name}
              subtitle={item.description}
              hideChevron={true}
              leftAvatar={{ source: { uri: baseUrl }}}
            />
          );
        }
        return (
          <View>
            <Image
              source={{ uri: baseUrl + 'images/ezywhip.png' }}
              style={{ width: 200, height: 200 }}
            />
            <FlatList 
              data={this.props.dishes} // <-- props.dishes is the dishes state
              renderItem={renderCategory}
              keyExtractor={item => item.id.toString()}
            />
          </View>
        );
      }
    }
    
    const mapStateToProps = state => ({
      dishes: state.dishes, // <-- the dishes array from the reducer
    });
    
    export default connect(mapStateToProps)(HomeScreen);
    

    【讨论】:

    • 是的,你是对的,我把它改成了 {this.props.disshes} 并且它工作正常。谢谢您的帮助。不过我还是有点困惑,因为我之前确实使用 {this.props.dishes.dishes} 让它工作了,这也是我之前的项目中它是如何正常工作的。
    • @AleistorCrawford 太棒了!有趣的是,我还没有看到您的其他代码或尝试,所以我无法与他们交谈,抱歉。如果您的问题得到解决,那么我邀请您接受答案,如果解释有帮助,那么也请投票(如果可以的话)。干杯。
    • 啊,我刚刚解决了,这是因为我这次使用的是 Flatlist,上次我使用的是我创建的用于显示卡片的 RenderItem 函数,而我使用的是 {this.props.菜.菜[0]}。非常感谢你的回答,谁知道我还要花多少小时哈哈
    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 2023-03-19
    • 2020-12-01
    • 1970-01-01
    • 2020-08-31
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多