React Redux CombineReducer |减速器未通过

时间:2019-02-27 21:54:46

标签: react-native redux react-redux

我的应用程序从一开始就一直使用redux,但仅使用一个reducer。推车减速器。现在我想添加另一个reducer,根据redux文档,combinedReducer是可行的方法。

现在,我已经阅读了文档,仔细研究了示例,并尝试在我的应用商店中实现CombineReducer。

我期望发生的事情:

可以在需要时分别调用两个reducer。

发生了什么事

当使用CombineReducer时,任何一个reducer都不起作用,但是除了在商店中时,每个reducer都可以单独工作。

作品:

import {createStore, combineReducers} from 'redux';
import cartItems from '../reducers/cartItems';
import getPayment from '../reducers/getPayment';

export default store = createStore(cartItems)

不起作用:

import {createStore, combineReducers} from 'redux';
import cartItems from '../reducers/cartItems';
import getPayment from '../reducers/getPayment';

const rootReducer = combineReducers({
    cartItems,
    getPayment,
  });

export default store = createStore(rootReducer)

商店-> Index.JS

import {createStore, combineReducers} from 'redux';
import cartItems from '../reducers/cartItems';
import getPayment from '../reducers/getPayment';

const rootReducer = combineReducers({
    cartItems,
    getPayment,
      });

export default store = createStore(rootReducer)

Reducer-> cartItems.JS

const cartItems = (state = [], action) => {
    switch (action.type)
    {
        case 'ADD_TO_CART':
        console.log('CarItems.JS', action.payload)
            if (state.some(cartItem => cartItem.id === action.payload.id)) {
                // increase qty if item already exists in cart
                return state.map(cartItem => (
                    cartItem.id === action.payload.id ? { ...cartItem, qty: cartItem.qty + 1 } : cartItem

                    ));

            }
            return [...state, { ...action.payload, qty: 1 }]; // else add the new item to cart

        case 'REMOVE_FROM_CART':
            return state
                .map(cartItem => (cartItem.id === action.payload.id ? { ...cartItem, qty: cartItem.qty - 1 } : cartItem))
                .filter(cartItem => cartItem.qty > 0);
    }
    return state
} 

export default cartItems 

App.JS

import React from 'react';
import AppNavigator from './navigation/AppNavigator';
import {Provider} from 'react-redux';
import store from './store';

export default class App extends React.Component {
    render() {
        return (
        <Provider store={store}>
            <AppNavigator />
        </Provider> 
        ) 
    }
}

CartScreen

import React, { Component } from 'react';
import { 
  View, 
  Text, 
  StyleSheet, 
  TouchableOpacity, 
  FlatList
} from 'react-native';
import {connect} from 'react-redux';
import Icon from "react-native-vector-icons/Ionicons";
import { addItemToCart, removeItem } from '../actions/ProductActionCreators';

const mapStateToProps = (state) => {
    let totalPrice = 0;
    state.map((item) => { // eslint-disable-line
      totalPrice += item.price * item.qty;
    });
    return {
        cartItems: state,
        totalPrice : totalPrice
    }
}
export class CartScreen extends Component{
    static navigationOptions = {
        header: null,
    };
    renderProducts = (products) => {
        return (
            <View key={products.index} style={styles.products}>
                <View style={styles.iconContainer}> 
                    <Icon name={products.item.icon} color="#DD016B" size={25} />
                </View>
                <View style={styles.text}>
                    <Text style={styles.name}>
                        {products.item.name} 
                    </Text>
                    <Text style={styles.price}>
                    € {products.item.price * products.item.qty}
                    </Text>
                </View>
                <View style={styles.buttonContainer}>
                    <TouchableOpacity style={styles.buttonContainer} onPress={() => this.props.removeItem(products.item)} > 
                        <Icon style={styles.button} name="ios-remove" color="white" size={25} />
                    </TouchableOpacity>
                    <Text style={styles.qty}>{products.item.qty}</Text>
                    <TouchableOpacity style={styles.buttonContainer} onPress={() => this.props.addItemToCart(products.item)} > 
                        <Icon style={styles.button} name="ios-add" color="white" size={25} />
                    </TouchableOpacity>

                </View>
            </View>
        )
    }
    render(){
        return (
            <View style={styles.container}>
                <Text style={styles.title}>Uw bestelling</Text>
                {console.log('CS', this.props.cartItems )}
                { 
                    this.props.cartItems.length>0?
                    <View>
                        <View style={styles.productContainer}>

                        <FlatList
                        style={styles.listContainer}
                        data={this.props.cartItems}
                        renderItem={this.renderProducts}
                        keyExtractor={(item, index) => index.toString()}
                        />
                        </View>
                        <View style={styles.optionsContainer}>
                            <Text style={styles.total}>Totaal: € {this.props.totalPrice} </Text>    
                            <TouchableOpacity style={styles.checkOutContainer}  onPress={() => this.props.navigation.navigate('Payment')}>  
                                <Icon style={styles.checkOutButton} name="ios-checkmark" color="white" size={35} />
                            </TouchableOpacity>
                        </View>
                    </View>
                    : 
                    <Text style={styles.emptyContainer}>No Items in your cart</Text>
                }
            </View>
        )
    }
}
const mapDispatchToProps =  {
    addItemToCart,
    removeItem
}
export default connect(mapStateToProps, mapDispatchToProps)(CartScreen);

CartIcon

import React from 'react';
import {
    View,
    Text,
    StyleSheet,
    Platform
} from "react-native";

import { withNavigation } from 'react-navigation';

import {connect} from 'react-redux';

import Icon from 'react-native-vector-icons/Ionicons';

const ShoppingCartIcon = (props) => (
    <View style={[{ padding: 5 }, Platform.OS == 'android' ? styles.iconContainer : null]}>
    <View style={{
        position: 'absolute', height: 30, width: 30, borderRadius: 15, backgroundColor: '#DD016B', right: 15, bottom: 15, alignItems: 'center', justifyContent: 'center', zIndex: 2000,

    }}>
        <Text style={{ color: 'white', fontWeight: 'bold' }}>{props.cartItems.length}</Text>
    </View>
    <Icon onPress={() => props.navigation.navigate('Cart')} name="ios-cart" color="white" size={30} />
</View>
) 

const mapStateToProps = (state) => {
    const {cartItems, getPayment} = state;
    return {
        cartItems: state
    }
}

 export default connect(mapStateToProps)(withNavigation(ShoppingCartIcon));

 const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    },
    iconContainer: {
        paddingLeft: 20, paddingTop: 10, marginRight: 5
    }
});

1 个答案:

答案 0 :(得分:1)

使用combineReducer时,您需要以其他方式访问redux状态。分别使用cartItemsgetPayment可以在mapStateToProps中访问state.cartItemsstate.getPayment状态。这是一种更新mapStateToProps函数的方法。

const mapStateToProps = (state) => {
    const {cartItems, getPayment} = state;
    let totalPrice = 0;
    cartItems.map((item) => { // eslint-disable-line
      totalPrice += item.price * item.qty;
    });
    return {
        cartItems: cartItems,
        totalPrice : totalPrice
    }
}


更新

对于CartIcon,您可以通过这种方式使用

const mapStateToProps = (state) => {
    return {
        cartItems: state.cartItems
    }
}

为说明起见,假设这是您从cartItems导出的当前Reducer -> cartItems.JS状态

{
  itemOne: {
    price: '$10',
    qty: 20
  },
  itemOne: {
    price: '$10',
    qty: 20
  },
}

使用combineReducers时,您在state函数中使用的mapStateToProps会像这样。您可以进行console.log(state)检查

const mapStateToProps = (state) => {
  console.log(state);
  /** this console.log will prints something like this
      state: {
        cartItems: {
          itemOne: {
            price: '$10',
            qty: 20
          },
          itemOne: {
            price: '$10',
            qty: 20
          },
        }
      },
      getPayment: {
        //your getPayment states
      }
  **/
  return {
    cartItems: state.cartItems
  }
}

这就是为什么要访问您的购物车商品,您需要执行state.cartItems