我是一个react初学者。在我的react-native应用程序中,我有一个从npmjs导入的Modal(“react-native-modal”)。我用它来制作一个用户输入时间的界面。enter image description here
现在,当我退出模态时,我打算将数据发送回父组件,并希望在发送给父组件的数据返回到同一组件后,在此处的圆圈中看到输入的持续时间,即:enter image description here
但实际上,我不会立即在圆圈中看到持续时间文本,只有当我再次进入模态并退出它时,我才会得到预期的输出。
代码如下所示:
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状态函数获取用户输入并将数据发送回父对象。
<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>
);
};
1条答案
按热度按时间fslejnso1#
查看此问题的答案:React Hooks: useEffect() is called twice even if an empty array is used as an argument
这似乎是一个类似的问题。