Итак, я начал работать в этой компании несколько месяцев go, и меня попросили отправлять запланированные электронные письма через день о машинах, у которых периодически возникали проблемы в течение определенного периода времени. Разработчик до меня создал сценарий, чтобы сделать это, но есть небольшая проблема с тем, как он решил это реализовать. Он был реализован так, что он решил создать компонент для этих запланированных электронных писем, используя node-shceduler, и этот компонент рендерился в методе рендеринга основных компонентов, который для меня был большим красным флажком. Проблема в том, что всякий раз, когда этот основной компонент отображается, запускается также запланированный сценарий, и при всех вызовах setState в главном компоненте компонент сценария отображается и отключает систему.
Я понимаю, что это очень неэффективно, и я чувствую, что это можно сделать лучше. Моя основная идея заключалась в том, чтобы разместить этот метод на стороне сервера, но проблема в том, что я не уверен, каким образом я смогу получить свои данные с базы данных на сервер, чтобы сделать это.
Вот мой Timedscripts. js file
export default class Timedscripts extends React.Component{
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
TimedScript(email){
let logs = this.props.logs;
let temp = [];
for(let j = 0; j < logs.length; j++){
if(logs[j].KioskID != 'Testing'){
temp.push(logs[j].KioskID)
}
}
let uniq = [... new Set(temp)];
let hash = [];
for(let i = 0; i < uniq.length; i++){
let count = 0;
for(let j = 0; j < temp.length; j++){
if(temp[j] == uniq[i]){
count = count + 1;
}
}
hash.push(count);
}
let results = [];
for(let k = 0; k < hash.length; k++){
if(hash[k] >= 2){
results.push(uniq[k]);
}
}
if(this.state.count3 == 0){
var r = schedule.scheduleJob('0 19 * * *', function(){ // schedule for 7pm everyday
if(results.length != 0){
var arrayToEmail = [];
for(var l = 0; l < results.length; l++){
arrayToEmail.push(results[l] + '\n')
}
var to = email;
var text =
`<div width="100%",style="text-align:left;">` +
`<h1 style="text-align:center;">Machines With Reccuring Issues</h1>` +
`<table border="1", width="100%">` +
`<tbody style="text-align:left;">` +
`<tr><td width="300">Machine(s) that have had 2 or more issues within the last 30 days.</td></tr>` +
arrayToEmail +
`</tbody>` +
`</table >` +
`</div >`;
console.log("Sending Email")
$.get("/send", { to: to, subject: 'Machines to Watch', text: text }, function (data) { });
}
})
this.setState({count: 1})
}
}
render(){
return(
<div>
<button id="30Days" onClick={() => this.TimedScript(this.props.msgList.EmailTo)} style={{display: 'none'}}></button>
</div>
);
}
}
Я обнаружил, что счетчик используется для того, чтобы этот модуль не создавал столько электронных писем столько раз, сколько рендеринг основного компонента, что опять же кажется очень плохим imo. «/ Send» отправляет электронное письмо со стороны сервера.
Вот основной компонент
export default class MainComponent extends React.Component{
... some methods and such
render(){
return(
<div>
...some html
<TimedScripts logs={this.state.LogHistory} inventoryItems={this.props.inventoryItems} alerts={this.props.alerts} issues={this.props.issues} info={this.props.kiosksInfo} starPaper={this.props.starPaper} msgList={this.props.msgList} completedJobs={this.props.completedJobs}/>
script{
setTimeout(function(){
$('#30Days').trigger('click')
}, 5000)
}
</div>
);
}
}
Как вы можете видеть, каждый раз при визуализации основного компонента этот компонент скрипта монтируется и запускаю его методы снова и снова.
Я получаю необходимую информацию от вызова сокетов в главном компоненте, который затем вызывает процедуру db, и эта информация затем передается в компонент TimedScripts. Если у кого-то есть идеи о том, как я могу просто сделать этот компонент рендерингом один раз, или если есть более эффективный способ сделать это, я был бы очень признателен! Спасибо.