如何解决如何与setInterval一起触发事件? JavaScript / React-toastify
的对象rooms: {
room01 : { timestamp: 10}
room02 : { timestamp: 10}
}
当用户单击按钮时,时间戳设置为10(通过调度)。如果有时间戳,我会倒数为0,然后在整个应用中使用react-toast
设置一个Notification。
问题是我在Notification组件上没有roomId可用,因为必须将Notification组件放置在应用程序的根目录下,否则它将被卸载并且我的Notification()逻辑不起作用。 (我可以在Notification或App中访问房间,但是它以数组形式存在,例如['room01','room02'],该数组也在redux中,但是我如何选择两个房间并访问其时间戳并运行该函数来倒计时?)。
基本上,我需要检查每个房间的redux存储区中是否有时间戳,如果有,则倒计数为0并显示带有roomId的通知。导航到其他页面时,通知/设置间隔应该可以工作。
My app component
import React from 'react';
import { Route,Switch,browserRouter } from 'react-router-dom';
import Home from './Home';
import 'react-toastify/dist/ReactToastify.css';
import Notification from '../features/seclusion/Notification';
const App = () => {
return (
<div>
<Notification /> // if I pass in room id like so roomId={'room02'} I cant get it to work for one room
<browserRouter>
<Switch>
<Route exact path="/room/:id" component={Room} />
<Route exact path="/" component={Home} />
</Switch>
</browserRouter>
</div>);
};
export default App;
import React,{ useState,useEffect } from 'react';
import { useSelector } from 'react-redux';
import 'react-toastify/dist/ReactToastify.css';
import { ToastContainer,toast,Slide } from 'react-toastify';
import moment from 'moment';
export default function Notification() {
const timestamp = useSelector(state => state.rooms); // need to get timestamp for room01 and room02
const [timestamp,setTimestamp] = useState(null);
const [timerId,setTimerId] = useState(null);
const notify = () => {
toast(<div>alert</div>,{
position: "top-center",});
};
useEffect(() => {
if (timestamp) {
const id = setInterval(() => {
setTimestamp((timestamp) => timestamp - 1)
},1000)
setTimerId(id);
}
return () => {
clearInterval(timerId);
};
},[timestamp]);
useEffect(() => {
if(timestamp === 0){
notify();
clearInterval(timerId);
}
},[timestamp])
return (
<ToastContainer
newestOnTop={true}
transition={Slide}
autoClose={false}
/>
);
}
解决方法
您可以在其他方法中执行以下操作,但是我认为以下操作是最好的,因为它使Notification组件更可重用,并且可以更好地利用职责分离,使代码更易于阅读,并且大多数重要的是要与React的声明式思维保持一致。
const App = () => {
const rooms = state.rooms // this is not redux syntax but i will leave that to you
return (
<div>
{Object.entries(rooms).map(([roomId,roomDetails]) => {
const {timestamp} = roomDetails;
// Obviously you now need to modify your Notification component to handle these props
return <Notification
timestamp={timestamp}
roomId={roomId} // actually its better to create the Notification component without the roomId prop and use the roomId to induce the message prop,this makes Notification component more reusable across other components
key={`${roomId}-${timestamp}`}
message="You might send message here instead of doing that inside the Notification component"
/>
// You might be interested to rename Notification to DelayedNotification or something else
}}
<BrowserRouter>
<Switch>
<Route exact path="/room/:id" component={Room} />
<Route exact path="/" component={Home} />
</Switch>
</BrowserRouter>
</div>);
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。