React Redux объединитьReducer |Редуктор не передается - PullRequest
0 голосов
/ 28 февраля 2019

Мое приложение использует редукс с самого начала, но только с одним редуктором.Тележка-редуктор.Теперь я хочу добавить еще один редуктор, и в соответствии с документами-редуктами, рекомендуется использовать CombineReducer.

Теперь я прочитал документы, посмотрел примеры и попытался внедрить объединениеReducer в мой магазин приложений.

То, что я ожидал, произойдет:

Оба редуктора можно вызывать индивидуально при необходимости.

Что произошло:

Ни один из этих редукторов не работает при использовании combReducer, но каждый редуктор работает индивидуально, когда только в магазине.

Работает:

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)

Store -> 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)

Редуктор -> 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 голосов
/ 28 февраля 2019

Когда вы используете combineReducer, вам нужно получить доступ к вашему состоянию притока по-другому.Ваши состояния cartItems и getPayment могут быть доступны в вашем mapStateToProps с помощью state.cartItems и state.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

...