[英]Why does this take double action to load data from parent?
我是一个反应初学者。 在我的 react-native 应用程序中,我有一个从 npmjs(“react-native-modal”)导入的模式。 我用它来制作一个用户输入时间的界面。 在此处输入图像描述
现在,当我退出模态时,我打算将数据发送回父组件,并且我希望在我发送给父组件的数据返回到同一组件后在此处的圆圈中看到输入的持续时间,即这个圆圈:输入图像在这里描述
但实际上我并没有立即在圆圈中看到持续时间文本,当我再次进入模态并退出时,我只会得到预期的 output。
代码如下:
const TimerBubble = ({
id,
title,
duration,
isRunning,
getTitleUpdate,
getDurationUpdate,
getIsRunningUpdate,
getDeletionUpdate,
}) => {
...
const [selectedHr, setSelectedHr] = React.useState(0);
const [selectedMin, setSelectedMin] = React.useState(0);
const [selectedSec, setSelectedSec] = React.useState(0);
const [secondsLeft, setSecondsLeft] = React.useState(duration);
useEffect(() => {
setSecondsLeft(duration);
}, [isDEV]);
...
下面是模态的代码,我在其中获取用户输入并使用 getDurationUpdate state function 将数据发送回父级。
<Modal
isVisible={isDEV}
onBackdropPress={() => {
setIsDEV(false);
getDurationUpdate([
id,
parseInt(selectedHr) * 3600 +
parseInt(selectedMin * 60) +
parseInt(selectedSec),
]);
}}
style={styles.modal}
>
...
...
</Modal>
Clockify 将持续时间转换为文本。
<View>
<Text>
{clockify.hr}
</Text>
</View>
我没有太多关于堆栈溢出问题的经验,所以如果这里无法理解的问题是我的完整代码。 我将不胜感激任何帮助。
const TimerBubble = ({
id,
title,
duration,
isRunning,
getTitleUpdate,
getDurationUpdate,
getIsRunningUpdate,
getDeletionUpdate,
}) => {
const [isDEV, setIsDEV] = React.useState(false);
const [isTimerPaused, setIsTimerPaused] = React.useState([null, false]);
const [selectedHr, setSelectedHr] = React.useState(0);
const [selectedMin, setSelectedMin] = React.useState(0);
const [selectedSec, setSelectedSec] = React.useState(0);
const [secondsLeft, setSecondsLeft] = React.useState(duration);
useEffect(() => {
setSecondsLeft(duration);
}, [isDEV]);
const [progress, setProgress] = React.useState(0);
useEffect(() => {
if (secondsLeft > 0) {
setProgress((secondsLeft / duration) * 100);
}
}, [secondsLeft]);
const clockify = () => {
let hours = Math.floor(secondsLeft / 3600);
let minutes = Math.floor((secondsLeft / 60) % 60);
let seconds = Math.floor(secondsLeft % 60);
let displayHours = hours < 10 ? `0${hours}` : hours;
let displayMinutes = minutes < 10 ? `0${minutes}` : minutes;
let displaySeconds = seconds < 10 ? `0${seconds}` : seconds;
return [displayHours, displayMinutes, displaySeconds];
};
return (
<View className="relative my-5">
<Modal
isVisible={isDEV}
onBackdropPress={() => {
setIsDEV(false);
getDurationUpdate([
id,
parseInt(selectedHr) * 3600 +
parseInt(selectedMin * 60) +
parseInt(selectedSec),
]);
}}
style={styles.modal}
>
<View className="bg-[#011C27] p-5 flex items-center rounded-2xl">
<View className="flex flex-row p-2">
<Text className="w-full text-left font-poppinsSBd text-3xl text-white/90">
{title}
</Text>
<TouchableOpacity
onPress={() => {
setIsDEV(false);
getDurationUpdate([
id,
parseInt(selectedHr) * 3600 +
parseInt(selectedMin * 60) +
parseInt(selectedSec),
]);
}}
>
<FontAwesomeIcon icon={faXmark} size={30} color={"#ffffff"} />
</TouchableOpacity>
</View>
<View className="flex flex-row justify-between w-full p-5">
<View className="w-[30%] flex items-center justify-center">
<Text className="font-poppinsBd text-white text-xl">
{TimeConstants.hrArr[selectedHr]} Hr
</Text>
<WheelPicker
onItemSelected={(index) => setSelectedHr(index)}
initPosition={selectedHr}
data={TimeConstants.hrArr}
style={styles.wheelPicker}
itemTextFontFamily={"Poppins-SemiBold"}
selectedItemTextFontFamily={"Poppins-Bold"}
selectedItemTextColor={"#FBFBF2"}
itemTextColor={"#A6A2A2"}
indicatorColor={"#ffffff"}
indicatorWidth={3}
selectedItemTextSize={30}
itemTextSize={25}
isCyclic={true}
/>
</View>
<View className="w-[30%] flex items-center justify-center">
<Text className="font-poppinsBd text-white text-xl">
{TimeConstants.minArr[selectedMin]} Min
</Text>
<WheelPicker
onItemSelected={(index) => setSelectedMin(index)}
initPosition={selectedMin}
data={TimeConstants.minArr}
style={styles.wheelPicker}
itemTextFontFamily={"Poppins-SemiBold"}
selectedItemTextFontFamily={"Poppins-Bold"}
selectedItemTextColor={"#FBFBF2"}
itemTextColor={"#A6A2A2"}
indicatorColor={"#ffffff"}
indicatorWidth={3}
selectedItemTextSize={30}
itemTextSize={25}
isCyclic={true}
/>
</View>
<View className="w-[30%] flex items-center justify-center">
<Text className="font-poppinsBd text-white text-xl">
{TimeConstants.secArr[selectedSec]} Sec
</Text>
<WheelPicker
onItemSelected={(index) => setSelectedSec(index)}
initPosition={selectedSec}
data={TimeConstants.secArr}
style={styles.wheelPicker}
itemTextFontFamily={"Poppins-SemiBold"}
selectedItemTextFontFamily={"Poppins-Bold"}
selectedItemTextColor={"#FBFBF2"}
itemTextColor={"#A6A2A2"}
indicatorColor={"#ffffff"}
indicatorWidth={3}
selectedItemTextSize={30}
itemTextSize={25}
isCyclic={true}
/>
</View>
</View>
</View>
</Modal>
<Progress value={progress} />
<Badge
id={id}
isRunning={isRunning}
duration={duration}
getDeletionUpdate={getDeletionUpdate}
getIsRunningUpdate={getIsRunningUpdate}
/>
<View
className="bg-white rounded-full flex items-center justify-center h-40 w-40 border-black"
style={false ? styles.active : null}
>
<TouchableOpacity
disabled={getIsRunningUpdate[1]}
onPress={() => {
setIsDEV(!isDEV);
}}
>
{clockify()[0] > 0 && (
<View className="flex flex-row space-x-1 items-center justify-center">
<TimeText time={clockify()[0]} />
<Text className="font-poppinsBd">hr</Text>
</View>
)}
<View className="flex flex-row space-x-1 items-center justify-center">
<TimeText time={clockify()[1]} />
<Text className="font-poppinsBd mr-1">m</Text>
<TimeText time={clockify()[2]} />
<Text className="font-poppinsBd">s</Text>
</View>
</TouchableOpacity>
<View className="border-t w-[70%] flex items-center">
<TextInput
className="font-poppinsBd text-sm w-full text-center placeholder:text-gray-400"
caretHidden={true}
defaultValue={title}
onEndEditing={(e) => getTitleUpdate([id, e.nativeEvent.text])}
/>
</View>
</View>
</View>
);
};
查看这个问题的答案: React Hooks: useEffect() is called twice even if an empty array is used as an argument
这似乎是一个类似的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.