反应原生延迟状态为什么需要700ms-1sec?



我有一张产品卡。你可以选择一个颜色。

我也有一个颜色组件

如果你选择了一种颜色,那么我将为selectedColor设置一个状态,像这样:

setSelectedColor(color);

所以我也把当前颜色发送给主组件(Product Card)。

如果按下selectedColor或者像这样更改,我还使用了useEffect

const [selectedColor, setSelectedColor] = useState('');
const handleChooseColor = color => {
setSelectedColor(color);
};
useEffect(() => {
// Send it to main Component (prop: onPress)
onPress(selectedColor);
}, [selectedColor]);

现在我在主组件中也设置了setSelectedColor。产品牌。

...
<Choose_Color onPress={color => setSelectedColor(color)} data={dataColor} />

Choose_color fullcode:

import React, { useState, memo, useEffect } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, FlatList } from 'react-native';
import pure from 'recompose/pure';
const Choose_Color = memo(({ data, onPress }) => {
const [selectedColor, setSelectedColor] = useState(null);
const handlePress = color => {
setSelectedColor(color);
}

useEffect(() => {
onPress(selectedColor);
}, [selectedColor]);
return (
<FlatList
data={data}
keyExtractor={item => item.key}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={() => handlePress(item.color)} style={[styles.colorButton, { backgroundColor: item.hex, borderColor: item.color === selectedColor ? 'red' : '#ddd' }]} />
)
}}
horizontal
showsHorizontalScrollIndicator={false}
removeClippedSubviews={true}
initialNumToRender={8}
maxToRenderPerBatch={1}
updateCellsBatchingPeriod={100}
/>
)

产品卡:

import React, { useState, useRef, useEffect, memo } from 'react';
import { StatusBar } from 'expo-status-bar';
import { useDispatch, useSelector } from 'react-redux';
import { StyleSheet, Animated, Text, View, Image, TouchableOpacity, Dimensions, TextInput, BackHandler } from 'react-native';
import { useNavigation } from '@react-navigation/core';
import { addCart } from '../redux/slice/product/shopping_cart';
import Product_stack_images from './FlatList/product_stack/Product_stack_images';
import { AntDesign, Ionicons } from '@expo/vector-icons';
import Stars from './Stars';
import Choose_Color from './FlatList/product_stack/Choose_Color';
import Choose_Size from './FlatList/product_stack/Choose_Size';
import Button from './FlatList/product_stack/Button';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { Modalize } from 'react-native-modalize';
import faker from 'faker';
import { Host, Portal } from 'react-native-portalize';
import { SnappingList } from './modal/Snapping';
import { ModalVideo } from './modal/ModalVideo';
import ButtonWithoutLoader from './ButtonWithoutLoader';
import Toast from 'react-native-toast-message';
const width = Dimensions.get('window').width;
// const height = Dimensions.get('window').height;
const ProductStack = ({ route }) => {
const { id, name, desc, username, product_image, user_profil_image, colors, size } = route.params;
const navigation = useNavigation();
const dispatch = useDispatch();
const modalizeRef = useRef(null);
const modalizeVideoRef = useRef(null);
/* Allow to press hardware button */
const [allow, setAllow] = useState(1);
const [amount, setAmount] = useState(1);
const [selectedSize, setSelectedSize] = useState(null);
const [selectedColor, setSelectedColor] = useState(null);

const [show, setShow] = useState(null);
/* Modal */
const animated = useRef(new Animated.Value(0)).current;
const modals = Array.from({ length: 8 }).map(_ => useRef(null).current);
const profile_image = faker.image.avatar();

const data = [
{
key: '1',
image: 'https://img01.ztat.net/article/spp-media-p1/9dcd25fef3f137e7ae494758e7c52545/bd500216513b46d9bea52787ea571205.jpg?imwidth=1800&filter=packshot'
},
{
key: '2',
image: 'https://img01.ztat.net/article/spp-media-p1/c3a9082e42283a23ba82616f6c3a6420/403b15ca90bf4d83acb2e59646be0a77.jpg?imwidth=1800'
}
];
const dataColor = [
{
key: "1",
hex: '#fff',
color: "white"
},
{
key: "2",
hex: '#000',
color: "black"
},
{
key: "3",
hex: '#2b80ff',
color: "blue" // #2b80ff
},
{
key: "4",
hex: '#FF0000',
color: "red"
},
];
const dataSize = [
{
key: '1',
size: 'XS'
},
{
key: '2',
size: 'S'
},
{
key: '3',
size: 'M'
},
{
key: '4',
size: 'L'
}
];
const [m, setM] = useState(false);
const openModalSetting = () => {
modalizeRef.current?.open();
};
const handleAddCart = () => {
setShow(prevState => !prevState);
dispatch(addCart({
type: 'NORMAL',
item: {
user_id: Math.floor(Math.random() * 3),
product_id: 1,
product_name: 'Calvin klein Bag',
price: 29.99,
selectedSize,
product_image: data[0].image,
amount,
username: 'Ester71',
}
})
);
};
const handleMinusAmount = () => {
amount > 1 && amount < 9999 && setAmount(prevState => prevState - 1);
};
const handleAddAmount = () => {
amount > 0 && amount < 9999 && setAmount(prevState => prevState + 1);
};
console.log(selectedColor);
return (
<View style={{flex: 1}}>
<Host>
<Animated.View style={{
flex: 1,
borderRadius: animated.interpolate({ inputRange: [0, 1], outputRange: [0, 12] }),
transform: [
{
scale: animated.interpolate({ inputRange: [0, 1], outputRange: [1, 0.92] }),
},
],
opacity: animated.interpolate({ inputRange: [0, 1], outputRange: [1, 0.75] }),
}}
>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" contentContainerStyle={{flexGrow: 1, width: '100%'}} showsVerticalScrollIndicator={false} style={styles.container}>
<StatusBar hidden />
<Product_stack_images data={data} />
<View style={styles.mainContainer}>
<View style={styles.mainHeader}>
<View style={styles.mainHeaderLeft}>
<Text style={styles.product_name}>Calvin Klein Bag</Text>
<Stars />
</View>
<View style={styles.mainHeaderRight}>
<Text style={styles.price}>29.<Text style={{fontSize: 16}}>99€</Text></Text>
</View>
</View>
<View style={styles.optionContainer}>
<Text style={styles.title}>Farbe</Text>
<Choose_Color onPress={color => setSelectedColor(color)} data={dataColor} />
</View>
<View style={styles.optionContainer}>
<Text style={styles.title}>Größe</Text>
<Choose_Size onPress={size => setSelectedSize(size)} data={dataSize} />
</View>
<View style={styles.optionContainer}>
<Text style={styles.title}>Produktbeschreibung</Text>
<Text style={styles.product_desc}>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</Text>
</View>
<View style={[styles.optionContainer, { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }]}>
<View style={styles.shippingContainer}>
<Ionicons name="ios-time-outline" size={24} color="#555" />
<Text style={styles.textShippingTime}>Lieferung in 1-2 Werktagen</Text>
</View>
<View style={styles.amountContainer}>
<View style={styles.amountView}>
<TouchableOpacity onPress={handleMinusAmount}>
<AntDesign name="minus" size={20} color="#555" />
</TouchableOpacity>
<TextInput value={amount.toString()} onChangeText={e => setAmount(e)} keyboardType="numeric" style={styles.amountText} />
<TouchableOpacity onPress={handleAddAmount}>
<AntDesign name="plus" size={20} color="#555" />
</TouchableOpacity>
</View>
</View>
</View>
<View style={styles.buttonContainer}>
<ButtonWithoutLoader title="In den Einkaufswagen" onPress={handleAddCart} />
</View>
</View>
</KeyboardAwareScrollView>
<Toast style={{position: 'absolute', zIndex: 2}} ref={(ref) => Toast.setRef(ref)} />
</Animated.View>
</Host>
</View>
)
};

我在一个组件中更新setSelectedColor而在另一个组件中更新setSelectedColor的原因是,如果我直接将颜色从Choose_color组件发送到Product_card,那么它也需要700ms-1秒,所以用户在700ms后看到选定的颜色,这很糟糕,所以我像上面这样使用它。

问题是现在如果我console.log我的setSelectedColor从我的产品卡文件,它显示在700ms-1sec

与其进行2次调用来更改颜色,不如在父组件中设置为1。这意味着您应该将'handlePress'函数以及'selectedColor'状态变量移动到'Product Card '中。然后将这两个参数通过props传递给Choose_Color对象。

最新更新