Итак, я сделал эту определенную функцию javascript в Symfony, и, к сожалению, теперь мне приходится переделывать все это в React-Redux, отправляя данные из бэкэнда Symfony в приложение React. К сожалению, я все еще новичок в React, и я не мог заставить его работать.
Вот моя проблема в деталях: У меня есть список, в котором показаны все автомобили, остановившиеся на моей стоянке, у каждого автомобиля есть значение даты и времени, которое показывает, когда этот автомобиль был припаркован, и другое целочисленное значение, показывающее, сколько минут этот автомобиль будет оставаться припаркованным.
Моя функция принимает значение даты и времени, преобразует его в формат UTC и добавляет к нему целочисленное значение минут. Таким образом, она дает мне время, когда машина должна выехать с парковки.
Затем он делает другое значение текущего времени: и выполняет эту функцию: endingtime - currentTime.
Таким образом, я получаю список всех автомобилей с обратным отсчетом времени перед каждым автомобилем.
Как я уже сказал, теперь мне нужно интегрировать эту функцию в React-Redux:
Вот мой код на PHP: Я бы рассчитал время истечения срока действия в самом классе сущностей
public function getExpiresAt()
{
$parkedAt= $this->getParkedAt();
$expires = clone $parkedAt;
$expires->modify('+' . $this->getTime() . ' min');
return $expires->format('U');
}
После этого я создаю диапазон, который несет это значение в ветке
<td>
<span class = "timer" data-expires = "{{ car.getExpiresAt() }}"></span>
</td>
и используйте эту функцию для создания обратного отсчета:
<script>
var timers = document.querySelectorAll('.timer')
function updateTimers () {
var rightNow = Math.floor((Date.now()/1000)+3600) // in seconds
timers.forEach(function (timer) {
var expires = parseInt(timer.dataset.expires) // in seconds
if (rightNow > expires) {
timer.innerText ='expired'
} else {
// console.info('expires',expires,'rightNow',rightNow);
var seconds = expires - rightNow
var minutes = Math.floor(seconds/60)
var hours = Math.floor(minutes/60)
var days = Math.floor(hours/24)
seconds = ('0' + String(seconds%60)).slice(-2)
minutes = ('0' + String(minutes%60)).slice(-2)
hours = ('0' + String(hours%24)).slice(-2)
timer.innerText = days + 'd ' + hours + 'h ' + minutes + 'm ' + seconds + 's'
}
})
setTimeout(function () {
updateTimers()
}, 100)
}
updateTimers()
</script>
и, наконец, это мой carList.js в моем приложении React:
import React from 'react';
import {Message} from "./Message";
import {Spinner} from "./Spinner";
export class CarList extends React.Component {
render() {
const {carList}=this.props;
console.info(carList);
if (null === carList){
return (<Message message = "No cars"/>);
}
return (
<div className = "card mb-3 mt-3 shadow-sm">
{ carList.map(car => {
return (
<div className = "card-body border-bottom" key = {car.id}>
<p className = "card-text mb-0">
{car.number}
</p>
<p className = "card-text">
<small className = "text-muted">{car.parkedAt}</small>
</p>
<p>
<span className = "timer"></span>
</p>
</div>
);
})}
</div>
)
}
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Могу предположить, что вы предоставите машине время пребывания в машине.
Итак, вы должны рассчитать обратный отсчет истечения срока действия в реакциях рендеринга:
{carList.map(car => {
return (
<div className = "card-body border-bottom" key = {car.id}>
.....
<p className = "card-text">
<small className = "text-muted">Experies in: {this.getExirationTime(car.expires)}</small>
</p>
....
</div>
);
})}
Затем вы объявите этот метод getExirationTime в нашем классе CarList. Кроме того, вы используете два метода реагирования (componentDidMount/componentDidUpdate), чтобы запланировать следующее обновление timeres путем повторного рендеринга этого компонента.
export class CarList extends React.Component {
componentDidMount() {
// Schedule the updates and forcer re-render if we had cars.
this.timer = setInterval(() => {
// this.props should be different each time.
const { carList } = this.props;
if (carList !== null && carList.length) {
this.forceUpdate()
};
}, 1000)
}
componentWillUnmount() {
clearInterval(this.timer);
}
getExirationTime(expireIn) {
// modified code from your code
var right Now = Math.floor((Date.now()/1000)+3600);
var expires = parseInt(timer.dataset.expires) // in seconds
if (rightNow > expireIn) {
return 'expired';
} else {
var seconds = expireIn - rightNow
var minutes = Math.floor(seconds/60)
var hours = Math.floor(minutes/60)
var days = Math.floor(hours/24)
seconds = ('0' + String(seconds%60)).slice(-2)
minutes = ('0' + String(minutes%60)).slice(-2)
hours = ('0' + String(hours%24)).slice(-2)
return days + 'd ' + hours + 'h ' + minutes + 'm ' + seconds + 's'
}
}
render() {
const {carList}=this.props;
console.info(carList);
......
И это все. Этот компонент будет обновляться каждую секунду, если в нем будут автомобили.
Вы можете сделать это на бэкенде, а затем просто использовать его, или отправить это время парковки во внешний интерфейс и рассчитать это время в getExirationTime(), где вы передадите его с помощью parkedAt. this.getExirationTime(car.parkedAt, car.time); Это на вас.
Еще раз большое спасибо чувак. Я считаю нормально, у меня есть небольшая ошибка, но это в основном потому, что я неправильно преобразовал дату истечения срока действия. Я исправляю это прямо сейчас.
на самом деле я еще не рассчитал срок действия, у меня просто есть parkedAt и Time, которые я должен преобразовать в UTC, а затем добавить, чтобы получить это значение