简体   繁体   中英

Why does this take double action to load data from parent?

I am a react beginner. In my react-native app I have a Modal imported from npmjs ("react-native-modal"). I used it to make an interface for time input from the user. enter image description here

Now, when I exit the modal I intend to send the data back to the parent component and I expect to see the entered duration in the circle here after the data I sent to parent comes backs to the same component ie, this circle: enter image description here

But in reality I don't see the duration text immediately in the circle, I only get the the expected output when I enter the modal again and exit it.

The code is provided below:

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]);

    ...

below is the code of the modal where i take user input and send the data back to parent with getDurationUpdate state function.

    <Modal
          isVisible={isDEV}
          onBackdropPress={() => {
            setIsDEV(false);
            getDurationUpdate([
              id,
              parseInt(selectedHr) * 3600 +
                parseInt(selectedMin * 60) +
                parseInt(selectedSec),
            ]);
          }}
          style={styles.modal}
        >
     ...
     ...
     </Modal>

Clockify converts the duration into text.

     <View>
         <Text>
          {clockify.hr}
         </Text>
     </View>

I don't have much experience with asking questions on stack overflow so if the question in non understandable here is my full code. I'd appreciate any kind of help.

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>
  );
};

Check out the answers to this question: React Hooks: useEffect() is called twice even if an empty array is used as an argument

It seems to be a similar issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM