我制作了一个像Amazon和Flipkart这样的应用程序,可以根据类别过滤产品。
import React, { useState,useEffect} from 'react'
import { FlatList,View,Image,Text,StyleSheet,TouchableOpacity,ActivityIndicator} from 'react-native';
import {useSelector , useDispatch} from "react-redux";
import ShopComponent from "../components/ShopComponent";
import * as cartActions from "../store/actions/Cart"
import * as ProductActions from "../store/actions/Product"
import {HeaderButtons,Item} from "react-navigation-header-buttons";
import HeaderButton from "../components/UI/HeaderComponent";
import Product from '../models/Product';
import ProductsList from "../data/DataTemp";
import SearchScreen from "./SearchScreen";
const SecondScreen =(props)=>{
const [CurrentCategory, setCurrentCategory] = useState([]);
const category = props.navigation.getParam("title");
const UpdatedCategory=useSelector(state =>
state.Products.availableProduct.filter((product)=>{
return product.category == category
} )
);
const dispatch=useDispatch();
useEffect(()=>{
setCurrentCategory(UpdatedCategory)
},[])
useEffect(()=>{
dispatch(ProductActions.fetchProduct());
},[dispatch])
const loadBooks = (itemData)=>{
let newBook = {
id : itemData.item.id,
title : itemData.item.title,
Description : itemData.item.Description,
image : itemData.item.image,
Price : itemData.item.Price,
category : itemData.item.category,
}
return (
<TouchableOpacity onPress={()=>{props.navigation.navigate("Detail",
{ productId: itemData.item.id,
productTitle:itemData.item.title } );
}}>
<View style={styles.productMain}>
<View style={{width:"35%", height:200, }}>
<Image style={{width : "100%" , height:"95%" , resizeMode:"contain", borderRadius:5}}
source={{uri : itemData.item.imageUrl}} />
</View>
<View style={{ justifyContent: "space-around", alignContent:"center", marginLeft:40,}}>
<View style={{overFlow:"hidden"}}>
<Text numberOfLines={1} style={styles.text}>{itemData.item.title}</Text>
</View>
<View>
<Text numberOfLines={1} style={styles.text}>Price : Rs {itemData.item.price}</Text>
</View>
</View>
</View>
</TouchableOpacity>
)
}
return (
<View style={styles.main}>
<FlatList
data={CurrentCategory}
keyExtractor={item => item.id}
renderItem={loadBooks}
/>
</View>
)
}
SecondScreen.navigationOptions = navData=>{
return{
headerTitle:"Deep Mart",
headerLeft:(()=><HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item title="ToggleDrawer" iconName={"md-menu" } onPress={()=>{navData.navigation.toggleDrawer();}}/>
</HeaderButtons>
),
headerRight:(()=><HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item title="cart" iconName={"md-cart" } onPress={()=>{navData.navigation.navigate("Cart")}}/>
</HeaderButtons>
), }
};
const styles = StyleSheet.create({
main: {
flex : 1,
padding : 10,
},
bookMain :{
marginTop:10,
width : "100%",
height:500,
borderColor:"black" ,
borderWidth:1,
borderRadius : 5
},
productMain: {
flexDirection:"row",
justifyContent:"flex-start",
borderBottomWidth:1,
marginBottom:10,
backgroundColor:"white",
borderRadius:10,
},
text : {
color:"black",
fontSize: 15,
fontWeight:"bold",
overflow:"hidden",
}
});
export default SecondScreen;
在这里,我使用了两个useEffect 用于过滤基于类别的标题,和用于从商店中的ProductAction获取产品。
import Product from "../../models/Product";
export const DELETE_PRODUCT = "DELETE_PRODUCTS";
export const CREATE_PRODUCT="CREATE_PRODUCT";
export const UPDATE_PRODUCT="UPDATE_PRODUCT";
export const SET_PRODUCTS = "SET_PRODUCTS"
export const SOLD_PRODUCTS = "SOLD_PRODUCTS"
export const fetchProduct=()=>{
return async dispatch => {
// any async code you want!
try {
const response= await fetch("https://direp-marct.firebaseio.com/products.json");
if (!response.ok) {
throw new Error('Something went wrong!');
}
const resData = await response.json();
const loadedproducts = [];
for(const key in resData) {
loadedproducts.push(
new Product(
key ,
"u1",
resData[key].title ,
resData[key].imageUrl ,
resData[key].description,
resData[key].price,
resData[key].mrp,
resData[key].category
)
);
}
dispatch({ type: SET_PRODUCTS, products: loadedproducts });
} catch (err) {
// send to custom analytics server
throw err;
}
};
};
export const deleteProduct=(ProductId)=>{
return async (dispatch) =>{
fetch(`https://direp-marct.firebaseio.com/products/${ProductId}.json`,{
method:"DELETE"
});
dispatch({type:DELETE_PRODUCT , pid:ProductId})
}
};
export const soldProduct=(ProductId)=>{
return async (dispatch) =>{
fetch(`https://direp-marct.firebaseio.com/products/${ProductId}.json`,{
method:"POST"
});
dispatch({type:DELETE_PRODUCT , pid:ProductId})
}
};
export const createProduct=(title , description ,imageUrl, price , mrp ,category)=>{
return async (dispatch)=>{
, {
const response= await fetch("https://direp-marct.firebaseio.com/products.json" ,
{
method:"POST",
header:{
"Content-Type":"Application/json"
},
body:JSON.stringify({
title,
description,
imageUrl,
price,
mrp,
category
})
});
const resData = await response.json();
dispatch({
type:CREATE_PRODUCT,
productData: {
id:resData.name,
title ,
imageUrl ,
description ,
price,
mrp,
category
}});
}
};
export const updateProduct=(id, title , description,imageUrl , price ,mrp, category)=>{
return async (dispatch)=>{
const response=await fetch(`https://direp-marct.firebaseio.com/products/${id}.json`,{
method:"PATCH",
header:{
"Content-type":"application.json"
},
body:JSON.stringify({
title,
description,
imageUrl,
price,
mrp,
category
})
})
dispatch( {
type:UPDATE_PRODUCT,
pid:id ,
productData:{ title,description, imageUrl , price,mrp ,category}}
)
}
};
这是我的减速器
import PRODUCTS from "../../data/dummy-data";
import {DELETE_PRODUCT , CREATE_PRODUCT , UPDATE_PRODUCT, SET_PRODUCTS , SOLD_PRODUCTS} from "../../store/actions/Product";
import Product from "../../models/Product";
const initialState={
availableProduct : [],
userProduct : []
};
export default (state=initialState , action) =>{
switch (action.type){
case SET_PRODUCTS:
return{
availableProduct:action.products,
userProduct:action.products
}
case CREATE_PRODUCT:
const newProduct = new Product(
action.productData.id,
'u1',
action.productData.title,
action.productData.imageUrl,
action.productData.description,
action.productData.price,
action.productData.mrp,
action.productData.category
);
return {
...state,
availableProduct: state.availableProduct.concat(newProduct),
userProduct: state.userProduct.concat(newProduct)
};
case UPDATE_PRODUCT:
const productIndex = state.userProduct.findIndex(
prod => prod.id === action.pid
);
const updatedProduct = new Product(
action.pid,
state.userProduct[productIndex].ownerId,
action.productData.title,
action.productData.imageUrl,
action.productData.description,
action.productData.price,
action.productData.mrp,
action.productData.category
);
const updatedUserProducts = [...state.userProduct];
updatedUserProducts[productIndex] = updatedProduct;
const availableProductIndex = state.availableProduct.findIndex(
prod => prod.id === action.pid
);
const updatedAvailableProducts = [...state.availableProduct];
updatedAvailableProducts[availableProductIndex] = updatedProduct;
return {
...state,
availableProduct: updatedAvailableProducts,
userProduct: updatedUserProducts
};
case DELETE_PRODUCT:
return {
...state,
userProduct: state.userProduct.filter(
product => product.id !== action.pid
),
availableProduct: state.availableProduct.filter(
product => product.id !== action.pid
)
};
}
return state;
};
问题是,当我运行我的应用程序并单击特定类别(例如,Baby Care)时,首先没有获取任何产品,而我看到了一个空白屏幕。但是当我第二次单击我的产品时,我看到了结果。
我想要的是,当我单击类别而不是空白页面时,我希望最初看到提取的产品。 我认为问题出在UseEffect上,我不知道该怎么做,因为我是本机反应的新手。
在此先感谢您的帮助。
答案 0 :(得分:0)
问题在于这两部分以及它们如何协同工作:
const UpdatedCategory=useSelector(state =>
state.Products.availableProduct.filter((product)=>{
return product.category == category
} )
);
useEffect(()=>{
setCurrentCategory(UpdatedCategory)
},[])
UpdatedCategory
来自useSelector
钩子,这意味着状态更改时其值将更新。
但是此useEffect
有一个空的依赖项数组[]
,这意味着setCurrentCategory
仅在安装组件时被调用一次。
您希望CurrentCategory
根据状态的变化保持更新,因此您需要在依赖项中加入UpdatedCategory
。
useEffect(()=>{
setCurrentCategory(UpdatedCategory)
},[UpdatedCategory])