This is my main.js file were am trying to add the countdown timer , but it is displaying in the first card , not in all the other cards .please help me to get the solution .
import { Grid } from "@mui/material";
import Timer from "../MainPage/Timer";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Typography from "@mui/material/Typography";
const Main = (props) => {
const getMain = () => {
return (
// return console.log(props);
<Card sx={{ m: 2, width: 400 }}>
<CardContent>
<Grid container spacing={2}>
<Grid item>
<span className="ui top attach label">
{/* Match {match["Match"]} */}
Match {props.match.Match}
</span>
</Grid>
<Grid item>
<Typography variant="h5" component="div">
{/* {match["Team_A"]} */}
{props.match.Team_A}
</Typography>
</Grid>
<Grid item>
<Typography sx={{ mb: 1.5 }} color="text.secondary">
{/* {match["Date"]}
*/}
{props.match.Date}
</Typography>
<Typography sx={{ mb: 1.5 }} color="text.secondary">
{
<Timer
remainingDate={props.match.Date}
remainingTime={props.match.Time}
/>
}
</Typography>
</Grid>
<Grid item className="ui right aligned">
<Typography variant="h5" component="div">
{/* {match["Team_B"]} */}
{props.match.Team_B}
</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
);
};
// setInterval(getMain, 1000);
return getMain();
};
export default Main;
Timer.js file
const Timer = (props) => {
// console.log(props);
var countDownDate = new Date(
props.remainingDate " " props.remainingTime
).getTime();
// Update the count down every 1 second
// var x = setInterval(function () {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
return days "d " hours "h " minutes "m " seconds "s ";
};
export default Timer;
if am using without setInterval it displays the remaining time in all the Cards but when i use the setInterval it displays only on the first card . below is the code with the setInterval .
without the use of setInterval
Timer.js
const Timer = (props) => {
// console.log(props);
var countDownDate = new Date(
props.remainingDate " " props.remainingTime
).getTime();
// Update the count down every 1 second
var x = setInterval(function () {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor(
(distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
);
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("tmr").innerHTML =
days "d " hours "h " minutes "m " seconds "s ";
}, 1000);
return (
<div>
<span id="tmr"></span>
</div>
);
};
export default Timer;
with the setInterval the output am getting is
CodePudding user response:
Check out this third-party library. It will make your life way more comfortable as it did mine. https://www.npmjs.com/package/react-compound-timer
CodePudding user response:
That's probably coz you are setting the content on the same element by id.
document.getElementById("tmr").innerHTML = ...
;
ID is same for all card items' timer and it replaces one.
Try creating dynamic IDs from props and use that.
const Timer = (props) => {
const { timerId } = props;
const timerEleId = `tmr${timerId}`;
.
.
.
document.getElementById(timerEleId).innerHTML = ...;
.
.
.
return (
<div>
<span id={timerEleId}></span>
</div>);
}
Also, you are using react and why use declarative way of getting element by id and set it? you should use state updates on useEffects
with setIntervals. Something similar: Fetch data from external Api with reactjs hooks in every 10 seconds