mapStateToProps返回空状态

时间:2020-07-24 09:13:15

标签: javascript react-native redux react-redux

我正在使用React-native和Redux制作一个应用程序。问题在于,运行程序时,redux似乎未返回有效状态。我的课程如下:

configure.js

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

export const ConfigureStore = () => {
    const store = createStore(
        combineReducers({
            dishes,
            comments,
            promotions,
            leaders
        }),
        applyMiddleware(thunk, logger)
    );

    return store;
}

baseUrl.js

export const baseUrl = 'http://localhost:3001/';

每个对象都有一个类似的文件: ** dihses.js **

import * as ActionTypes from './ActionTypes';

export const dishes = (state ={
    isLoading: true, // it is true if the data is being loaded from the sever
    errMess: null, // Message to be shown if there is any error
    dishes: [] // array that contains the details of the 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;
    }
};

App.js

import React from 'react';
import Main from './components/MainComponents';
import { Provider } from 'react-redux';
import { ConfigureStore } from './redux/configure';

const store = ConfigureStore();

// It just renders the mainComponent
export default class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Main />
      </Provider>
    );
  }
}

MainComponent.js

import React, { Component } from 'react';
import {Image, StyleSheet, ScrollView, View, Text } from 'react-native';
import { NavigationContainer, DrawerActions } from '@react-navigation/native';
import { createDrawerNavigator, DrawerItemList, } from '@react-navigation/drawer';
import { SafeAreaView } from 'react-native-safe-area-context';
import MenuNavigator from './navigation/MenuNavigator';
import ContactNavigator from './navigation/ContactNavigator';
import AboutUsNavigator from './navigation/AboutUsNavigator';
import HomeNavigator from './navigation/HomeNavigator';
import { Icon } from 'react-native-elements';
import "@fortawesome/fontawesome-free/js/all";
import { connect } from 'react-redux';
//import { baseUrl } from '../shared/baseUrl';
import { fetchDishes, fetchComments, fetchPromos, fetchLeaders } from '../redux/ActionCreators';

const mapStateToProps = state => {
    return {
    }
  }
  
const mapDispatchToProps = dispatch => ({
  fetchDishes: () => dispatch(fetchDishes()),
  fetchComments: () => dispatch(fetchComments()),
  fetchPromos: () => dispatch(fetchPromos()),
  fetchLeaders: () => dispatch(fetchLeaders()),
})

const MainNavigator = createDrawerNavigator()
const DrawerNavigation  = () => (
  <MainNavigator.Navigator backgroundColor='#D1C4E9' drawerContent={(props) => <CustomDrawerContentComponent {...props} />} >
    <MainNavigator.Screen name="Home" component={HomeNavigator} options={{drawerIcon:({ color }) => (<Icon name="home" type="font-awesome" size={24} color={color}/>)}}/>
    <MainNavigator.Screen name="Menu" component={MenuNavigator} options={{drawerIcon:({ color }) => (<Icon name="th-list" type="font-awesome" size={24} color={color}/>)}}/>
    <MainNavigator.Screen name="Contact" component={ContactNavigator} options={{drawerIcon:({ color }) => (<Icon name="address-card" type="font-awesome" size={22} color={color}/>)}}/>
    <MainNavigator.Screen name="About us" component={AboutUsNavigator} options={{drawerIcon:({ color }) => (<Icon name='info-circle' type="font-awesome" size={24} color={color}/>)}}/>
  </MainNavigator.Navigator>
)

const CustomDrawerContentComponent = (props) => (
  <ScrollView>
    <SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
      <View style={styles.drawerHeader}>
        <View style={{flex:1}}>
        <Image source={require('./images/logo.png')} style={styles.drawerImage} />
        </View>
        <View style={{flex: 2}}>
          <Text style={styles.drawerHeaderText}>Ristorante Con Fusion</Text>
        </View>
      </View>
      <DrawerItemList {...props} />
    </SafeAreaView>
  </ScrollView>
);

class Main extends Component {
  // When the main component mounts, the program will issue the dispatch for the four of them. Each of them will issue a fetch to the server to obtain the data
  // once the data is obtained, it will be loaded into the Redux store
  componentDidMount() {
    this.props.fetchDishes();
    this.props.fetchComments();
    this.props.fetchPromos();
    this.props.fetchLeaders();
  }

  render() {
 // as two elements can not be returned at the same time, it is necessary to embed them inside a View
 // Uses menu dishes passing it the state of the dishes
 // We add this Platform.OS == "ios"? 0 : Expo.Constants.statusBarHeight because, in android, with stack navigation the app will add a bar with back arrow at the paddingTop
      return (
        <NavigationContainer>
            <DrawerNavigation/>
        </NavigationContainer>    
      );
  }
 
}
const styles = StyleSheet.create({
  container:{
    flex:1
  },
  drawerHeader:{
    backgroundColor: '#512DA8',
    height: 140,
    alignItems: 'center',
    justifyContent: 'center',
    flex: 1,
    flexDirection: 'row'
  },
  drawerHeaderText:{
    color: 'white',
    fontSize: 24,
    fontWeight: 'bold'
  },
  drawerImage:{
    margin: 10,
    width: 80,
    height: 60
  }
})

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

HomeComponent.js

import { connect } from 'react-redux';
import { baseUrl } from '../shared/baseUrl';

const mapStateToProps = state => {

    return {
      dishes: state.dishes
    }
  }

function RenderItem(props)
{
    const item = props.item;

    if (item!=null)
    {
        return(
            <Card
            featuredTitle = {item.name}
            featuredSubtitle = {item.designation}
            image={ {uri: baseUrl + item.image} }
            >
                <Text style={{margin:10}}>{item.description}</Text>
            </Card>
            
        );
    }
    else
    {
        return(<View><Text>NULL ITEM</Text></View>
            
            );
    }
}
class Home extends Component{
    
    static navigationOptions ={
        title: 'Home',
        drawerLabel: 'Home',
        backgroundColor: '#d1d9e3'
    };

    render(){
        return(
            <ScrollView>
                <Text>this.props.dishes.dishes: {this.props.dishes.dishes}</Text>
                <RenderItem
                // Only select items whose featured prop is set to true
                    item = {this.props.dishes.dishes.filter((dish) => dish.featured)[0]}
                
            </ScrollView>
        );
    }
}

export default connect(mapStateToProps)(Home);

我的问题是,renderItem部分似乎并没有收到餐具对象,而是执行了“ null”的for部分,所以我想知道为了使商店和我的应用之间的成功交流。

1 个答案:

答案 0 :(得分:1)

创建商店时,应将初始状态作为第二个值。

export const ConfigureStore = () => {
  const store = createStore(
    combineReducers({
        dishes,
        comments,
        promotions,
        leaders
    }),
    INITIALSTOREOBJECT,
    applyMiddleware(thunk, logger)
  );

  return store;
}

您可以在官方文档here中阅读有关Redux中createStore函数的更多信息。