1

How to fetch time when submit button is clicked from app component. I have two separate component a Timer component and a App component.

when i click on submit button from app component it should take current time snapshot from timer component and send it to app component

I don't want to use Submit in timer component

Is it possible to do in React ?

Here is app component

export default function App() {
  return (
    <div className="App">
      <h2>Start editing to see some magic happen!</h2>
      <h3>Time: </h3>
      <button >Submit</button>
      <Timer  />
    </div>
  );
}

Here is Timer Component

export default function Time() {
  const [counter, setCounter] = React.useState(0);

  React.useEffect(() => {
    let countersystem;
    countersystem = setTimeout(() => setCounter(counter + 1), 1000);

    return () => {
      clearTimeout(countersystem);
     };
  }, [counter]);


  return (
    <div className="App">
      <div>Countdown: {counter}</div>
    </div>
  );
}
Parth Tiwari
  • 466
  • 8
  • 23

2 Answers2

1

To achieve what you want I added two states to the <App> component (counter and trigger) and sent the counter set state function of the <App> component to the <Timer>, and used trigger state variable to check if the timer should continue or not, here is a snippet of what I did and also you can check this snippet for working sample:

import React from "react";
import "./styles.css";

function Timer({ onTick, active }) {
  const [counter, setCounter] = React.useState(0);

  React.useEffect(() => {
    let countersystem;
    countersystem = setTimeout(() => setCounter(counter + 1), 1000);

    return () => {
      clearTimeout(countersystem);
    };
  }, [counter]);

  React.useEffect(() => {
    if (active) {
      onTick(counter);
    }
  }, [active]);

  return (
    <div className="App">
      <div>Countdown: {counter}</div>
    </div>
  );
}

export default function App() {
  const [counter, setCounter] = React.useState(0);
  const [tigger, setTrigger] = React.useState(0);

  return (
    <div className="App">
      <h2>Start editing to see some magic happen!</h2>
      <h3>Time: {counter}</h3>
      <button
        onClick={() => {
          setTrigger(tigger + 1);
        }}
      >
        Submit
      </button>
      <Timer onTick={setCounter} active={tigger} />
    </div>
  );
}
ROOT
  • 11,363
  • 5
  • 30
  • 45
1

Here you go :

You have to take 2 state on App level

1 : snapshotTrigger to trigger to timer component get current snapshot via useEffect

2 : snapshot maintain last/current snapshot

You can run the below code snippet, hope that will clear your doubts :

const { useState , useEffect } = React;

function Timer({snapshotTrigger , getSnapshot }) {
  const [counter, setCounter] = useState(0);
  
  // ------------ START : ADDED -----------
  useEffect(() => {
    if (snapshotTrigger) {
      getSnapshot(counter);
    }
  }, [snapshotTrigger]);
  // ------------ END : ADDED -----------

  useEffect(() => {
    let countersystem;
    countersystem = setTimeout(() => setCounter(counter + 1), 1000);

    return () => {
      clearTimeout(countersystem);
    };
  }, [counter]);


  return (
    <div className="App">
      <div>Countdown: {counter}</div>
    </div>
  );
}

function App() {

  // ------------ START : ADDED -----------
  const [snapshotTrigger, setSnapshotTrigger] = useState(0);
  const [snapshot, setSnapshot] = useState(0);
  // ------------ START : END -----------

  return (
    <div className="App">
      <h2>Start editing to see some magic happen!</h2>
      <h3>Time: {snapshot}</h3>
      <button onClick={() => setSnapshotTrigger(snapshotTrigger + 1)}>Submit</button>
      <Timer snapshotTrigger={snapshotTrigger} getSnapshot={setSnapshot} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('react-root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>
Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122