React-Redux | Productlist | Add/Remove w/ BindActionCreator



我正试图在React中创建一个产品列表,在那里我可以添加和删除产品。

我开始研究如何使用redux框架/平台和本地进行反应

我已经有了一个函数productList容器、product组件和cartListcartProduct组件。

我的问题是:

产品:我只能添加产品而不能删除

购物车:反之亦然+购物车不会更新购物车项目的状态。

我已经添加了bindActionCreator,但还不知道如何将其应用于我的productList。

我预计会发生什么我正在尝试在同一个容器/组件中添加和删除react存储中的产品。

我该怎么做?我的方法是正确的还是完全错了?

提前谢谢你。

产品操作创建者

export const ADD_TO_CART = 'ADD_TO_CART'
export const REMOVE_FROM_CART = 'REMOVE_FROM_CART'
export function addItemToCart(row) {
return {
type:'ADD_TO_CART', 
payload: row, qty
}
}
export function removeTodo(row) {
return {
type:'REMOVE_FROM_CART' , 
payload: row, qty
}
}

产品列表(简化)

import React from 'react';
import { Component } from 'react';
import { 
View,  
StyleSheet, 
Text
} from 'react-native';
import Products from '../components/Products';
import { bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import * as ProductActionCreators from '../actions/ProductActionCreators'
export  class ProductList extends React.Component {
static navigationOptions = {
header: null,
};
constructor(props) {
super(props);
const { rows } = this.props.navigation.state.params;
const arrays = Object.values( {rows});
this.state = {
arrays,
filteredProducts: arrays,
};
const { dispatch } = props
this.boundActionCreators = bindActionCreators(ProductActionCreators, dispatch)
console.log(this.boundActionCreators)
}

render() {
return (
<View style={styles.container} >
<Text style={styles.title} >
{this.state.arrays[0].name}
</Text>
<Products products={this.state.arrays[0].data} onPress=
//Trying to change this to multiple actions
{this.props.addItemToCart}/>    
</View>
)
}
}
const qty = 0;
const mapDispatchToProps = (dispatch) =>{
//need to add BindActionCreator
return{
addItemToCart:(row) => dispatch({
type:'ADD_TO_CART', payload: row, qty
}),
removeItem:(product) => dispatch ({
type:'REMOVE_FROM_CART' , payload: product, qty
})  
}
}
export default connect(null, mapDispatchToProps) (ProductList);

产品(简化)

import React, { Component } from "react";
import {
View,
Text,
TouchableOpacity,
TextInput,
FlatList,
} from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
class Products extends Component {
constructor(props) {
super(props);
const { products } = this.props;
this.state = {
products, 
filteredProducts: products,
};
}
renderProducts = (products) => {
return (
<View key={products.index}>
<View> 
<Icon name={products.item.icon} color="#DD016B" size={25} />
</View>
<View>
<Text style={styles.name}>
{products.item.name}
</Text>
<Text>
€ {products.item.price}
</Text>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={() => this.props.onPress(products.item)} > 
<Icon name="ios-add" color="white" size={25} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.onPress(products.item)} > 
<Icon name="ios-remove" color="white" size={25} />
</TouchableOpacity>
</View>
</View>
)
}
render() {
return (
<View>
<FlatList
style={styles.listContainer}
data={this.state.filteredProducts}
renderItem={this.renderProducts}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
export default Products;

减速器/cartItems

const cartItems = (state = [], action) => {
switch (action.type)
{
case 'ADD_TO_CART':
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 

商店/索引

import {createStore} from 'redux';
import cartItems from '../reducers/carItems';
export default store = createStore(cartItems)

应用程序结构(简化)

Main folder
↳
Containers(folder)
↳
ProductsList.js
CartList.js
Components(folder)
↳
Product.js
cartProduct.js
Reducers(folder)
↳
carItems.js
Actions(folder)
↳ 
ProductActionCreators.js
Navigation(folder)
↳
AppNavigator,js
MainTabNavigator.js
Assets(folder for images etc.)
Store(folder)
↳
index.js
App.JS
Data.JS (using static JSON file for this development phase)

您有两个不同的操作,addItemToCartremoveItem,它们是在mapDispatchToProps中定义的。既然您指定了一个要连接的mapDispatchToProps参数,那么调度方法就不能作为连接组件的道具使用,相反,mapDispatchToProps返回的方法只能作为使用

其次,您不需要使用bindActionCreators,而且绝对不需要在组件中使用。MapDispatchToProps可以只是一个对象,connect将在内部使用dispatch。

第三个,您需要将添加和删除操作都传递给子组件。

第四个您可以将多个操作简单地作为道具传递给产品组件

你的代码看起来像

ProductActionCreators.js

export const ADD_TO_CART = 'ADD_TO_CART'
export const REMOVE_FROM_CART = 'REMOVE_FROM_CART'
export function addItemToCart(row) {
return {
type:'ADD_TO_CART', 
payload: row
}
}
export function removeItem(item) {
return {
type:'REMOVE_FROM_CART' , 
payload: item
}
}

产品列表

import React from 'react';
import { Component } from 'react';
import { 
View,  
StyleSheet, 
Text
} from 'react-native';
import Products from '../components/Products';
import { connect } from 'react-redux';
import { addItemToCart, removeItem } from '../actions/ProductActionCreators';
export  class ProductList extends React.Component {
static navigationOptions = {
header: null,
};
constructor(props) {
super(props);
const { rows } = this.props.navigation.state.params;
const arrays = Object.values( {rows});
this.state = {
arrays,
filteredProducts: arrays,
};
}

render() {
return (
<View style={styles.container} >
<Text style={styles.title} >
{this.state.arrays[0].name}
</Text>
<Products products={this.state.arrays[0].data} addItemToCart={this.props.addItemToCart} removeItem={this.props.removeItem}/>    
</View>
)
}
}

const mapDispatchToProps =  {
addItemToCart,
removeItem
}
export default connect(null, mapDispatchToProps) (ProductList);

产品

import React, { Component } from "react";
import {
View,
Text,
TouchableOpacity,
TextInput,
FlatList,
} from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
class Products extends Component {
constructor(props) {
super(props);
const { products } = this.props;
this.state = {
products, 
filteredProducts: products,
};
}
renderProducts = (products) => {
return (
<View key={products.index}>
<View> 
<Icon name={products.item.icon} color="#DD016B" size={25} />
</View>
<View>
<Text style={styles.name}>
{products.item.name}
</Text>
<Text>
€ {products.item.price}
</Text>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={() => this.props.addItemToCart(products.item)} > 
<Icon name="ios-add" color="white" size={25} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.removeItem(products.item)} > 
<Icon name="ios-remove" color="white" size={25} />
</TouchableOpacity>
</View>
</View>
)
}
render() {
return (
<View>
<FlatList
style={styles.listContainer}
data={this.state.filteredProducts}
renderItem={this.renderProducts}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
export default Products;

代码在大多数情况下看起来都很好。

ProductList中的react redux连接部分看起来不正常。数量总是0。应该是1。

此外,应该提供mapStateToProps以从购物车中获取产品。

在您的ProductList中,我会这样处理操作绑定:

const mapDispatchToProps = (dispatch) =>{
return bindActionCreators({
addItemToCart: (row, qty) => dispatch({
type:'ADD_TO_CART', payload: {row, qty}
}),
removeItem: (product, qty) => dispatch({
type:'REMOVE_FROM_CART' , payload: {product, qty}
})  
})
}
export default connect(null, mapDispatchToProps)(ProductList);

从组件的构造函数中删除操作绑定,因为这是不必要的。

您可能希望将代码拆分为Container/Component/HOC方法,因为我发现它使代码更易于阅读。由于您已经在单独的文件中定义了您的操作,所以我也会导入这些操作,而不是重新声明它们。

如果你遵循这个建议,你最终会得到以下结果:

container.js

import { bindActionCreators } from 'redux';
import ProductList from './product-list';
// Actions
import { addItemToCart, removeItem } from './actions';
function mapStateToProps(state) {
return {}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
addItemToCart,
removeItem,
})
}
export default connect(mapStateToProps, mapDispatchToProps)(ProductList);

产品列表.js

import React from 'react';
import { View, Text } from 'react-native';
import Products from '../components/Products';
export  class ProductList extends React.Component {
static navigationOptions = {
header: null,
};
constructor(props) {
super(props);
const { rows } = this.props.navigation.state.params;
const arrays = Object.values( {rows});
this.state = {
arrays,
filteredProducts: arrays,
};
this.handleProductPress = this.handleProductPress.bind(this);
}
handleProductPress(e) {
e.preventDefault();
// This is pseudo code...
this.props.addItemToCart(e.target.value, 1);
return;
} 
render() {
return (
<View style={styles.container} >
<Text style={styles.title} >
{this.state.arrays[0].name}
</Text>
<Products products={this.state.arrays[0].data} onPress={this.handleProductPress} />
</View>
) 
}
}
export default ProductList;

玩一玩,看看你进展如何。

相关内容

  • 没有找到相关文章

最新更新