![](/img/trans.png)
[英]How to get updated redux-toolkit state when component is not re-render
[英]react-native: how to re-rendered memo component when redux-toolkit state changes
我有一个由flatList
和组件内部呈现的产品列表,我请求一个产品图像并将其存储在 redux 商店中问题是当图像更新时组件不会重新呈现
产品视图组件:
const ProductView: FC<Props> = ({ price }: Props): ReactElement => {
const basketItem = useReduxSelector((state) =>
state.basket.items.find((item) => item.item.id === price.id)
);
const productImage = useReduxSelector(state => state.product.productImage.find((item) => item.id === price.id));
const [isFocused, setIsFocused] = useState<boolean>(false);
const [image, setImage] = useState<string>(productDefaultImage);
const useDispatch = useReduxDispatch();
useEffect(() => {
const getProductImage = async () => {
const token: string | null = await localStorage.getValue("token");
getProductImageById(token!, price.id.toString())
.then((res) => {
if (res.data.fileContent !== "") {
useDispatch(updateProductImage({ id: price.id, fileName: res.data.fileName, fileContent: `data:image/jpeg;base64,${res.data.fileContent}` }))
} else if (res.data.fileContent === "") {
setImage(productDefaultImage);
}
})
.catch((error) => {
console.log(error);
});
};
if (!productImage)
getProductImage();
else setImage(productImage.fileContent)
});
console.log('Rendering product item with id:', price.priceId);
return (
<Layout style={styles.container}>
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Image
source={{
uri: image
}}
resizeMode="contain"
style={{ width: 100, height: 70 }}
/>
<View style={styles.priceContainer}>
<Text style={styles.priceText}>{price.price}</Text>
<Text style={styles.currencyText}>دم</Text>
</View>
<PriceType
quantityType={
price.sellUnit === SellUnitEnum.ATOMIC
? price.atomicRtlName
: price.packingRtlName
}
/>
</View>
<View style={{ flex: 3 }}>
<View
style={{
flex: 1,
flexDirection: "row-reverse",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Text
style={{
width: "75%",
textAlign: "right",
fontFamily: "almarai-bold",
marginRight: 3,
}}
>
{price.rtlName}
</Text>
{price.withPoints ? <AwalPoint points={price.points} backgroundColor={Colors.gray200} textColor={Colors.gray800} /> : <View></View>}
</View>
<View style={{ flex: 1, flexDirection: "row-reverse" }}>
<PackageQuantity
title={price.atomicRtlName.toString() + " في"}
packageName={price.packingRtlName}
quantity={price.packageQuantity.toString()}
image={require("../assets/surprise.png")}
backgroundColor={Colors.primary400}
containerStyle={{ flex: 1 }}
/>
<PackageQuantity
title="تمن"
packageName={
price.sellUnit === "ATOMIC"
? price.packingRtlName
: price.atomicRtlName
}
quantity={
(price.sellUnit === "ATOMIC"
? (price.price * price.packageQuantity).toFixed(2)
: (price.price / price.packageQuantity).toFixed(2)
).toString() + " دم"
}
image={require("../assets/dollar.png")}
backgroundColor={Colors.secondary400}
containerStyle={{ flex: 1.5 }}
/>
</View>
<View style={{ flex: 1, flexDirection: "row", paddingBottom: 7 }}>
{basketItem === undefined && !isFocused ? (
<Button
style={{
height: 45,
borderWidth: 0,
borderRadius: 100,
backgroundColor: Colors.secondary500,
}}
onPress={() => {
useDispatch(updateItems({ item: price, quantity: 1, error: undefined, productImage: image }));
}}
accessoryRight={IconComponent(evaIcons.cart, Colors.white500)}
>
{(props) => (
<Text
{...props}
style={{
fontFamily: "almarai-bold",
fontSize: 15,
color: Colors.white500,
}}
>
أضف إلى السلة
</Text>
)}
</Button>
) : (
<CounterInput
style={{ flex: 1 }}
priceId={price.id}
isFocused={isFocused}
setIsFocused={setIsFocused}
maxValue={price.storeQuantity}
buttonStyle={{ backgroundColor: Colors.primary500, borderWidth: 0 }}
/>
)}
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'flex-end' }}>
{(price.isDiscountable === true) ?
<View style={{ flexDirection: 'row-reverse', justifyContent: 'center', alignItems: 'center' }}>
<Image
source={require("../assets/promo.png")}
resizeMode="contain"
style={{ width: 30, height: 30 }}
/>
<Text style={{ textAlign: 'center', fontFamily: 'almarai-regular' }}>فيه روميز</Text>
</View> : null}
</View>
</View>
</View>
</Layout>
);
};
const isChanged = (prev: Props, next: Props) => {
return prev.price === next.price;
}
export default memo(ProductView, isChanged)
目标:我想在图像 state 更改时重新渲染组件,有什么办法可以做到这一点吗?
在阅读了有关备忘录的更多信息后,我发现了名为useMemo()
的反应钩子,因此通过将useEffect()
钩子替换为 useMemo( useMemo()
来解决我的问题
useMemo(() => {
const getProductImage = async () => {
const token: string | null = await localStorage.getValue("token");
getProductImageById(token!, price.id.toString())
.then((res) => {
if (res.data.fileContent !== "") {
useDispatch(updateProductImage({ id: price.id, fileName: res.data.fileName, fileContent: `data:image/jpeg;base64,${res.data.fileContent}` }))
}
})
.catch((error) => {
console.log(error);
});
};
if (!productImage)
getProductImage();
else setImage(productImage.fileContent)
}, [productImage?.fileContent])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.