我的应用程序从一开始就一直使用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
}
});
答案 0 :(得分:1)
使用combineReducer
时,您需要以其他方式访问redux状态。分别使用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