I’m trying to create an interface to be able to monitor the outputs of a relay board.
When the page is loaded, the status of the output is set by changing the image of the component. I want read the status of the outputs every 1 second and update the relative component.
If I open another tab where I go to change the status of the output automatically I have to change the status of the first tab as well.
I don’t know how to make react render only the component that has changed
import React, { useState, useEffect } from 'react'
import EventBus from "../common/EventBus";
import api from "../services/api";
import Device from "../components/Device"
const serverLink = "http://localhost:8080";
const Devices = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [errorCode, setErrorCode] = useState("")
const [state, setState] = useState()
const [refreshInterval, setRefreshInterval] = useState(4000)
async function setDevice(_id, outId, value) {
try {
const response = await api({ url: `${serverLink}/api/device/setdevice`, method: "POST", data: { _id: _id, outId: outId, value: value } })
if (response.data.status === "error") {
setError(true)
setErrorCode(response.data.description)
setLoading(false)
}
} catch (error) {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setErrorCode(_content);
if (error.response && error.response.status === 403) {
EventBus.dispatch("logout");
}
}
}
async function getStatus() {
try {
const response = await api.get(`${serverLink}/api/device/getstatus`)
if (response.data.status === "error") {
setError(true)
setErrorCode(response.data.description)
setLoading(false)
} else {
setState(response.data.data)
setLoading(false)
}
} catch (error) {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setErrorCode(_content);
if (error.response && error.response.status === 403) {
EventBus.dispatch("logout");
}
}
}
useEffect(() => {
getStatus()
const interval = setInterval(getStatus, refreshInterval)
return () => clearInterval(interval);
}, []);
return (
<div className='conteiner-rw'>
{loading ? "caricamento..." : error ? <p>{errorCode}</p> :(
state.map((dev) => {
return dev.out.map((el, index) => {
return <Device key={index} {...el} _id={dev._id} setDevice={setDevice} />
})
}))
}
</div>
)
}
export default Devices
The device component
import React, { useState, useEffect } from 'react';
import image from "../assets/image/image"
const Device = ({ id, _id, name, type, value, setDevice }) => {
const [state, setState] = useState(value)
const changeState = () => {
if (state == 1) {
setState(0)
setDevice(_id, id, 0)
} else if (state == 0) {
setState(1)
setDevice(_id, id, 1)
}
}
return (
<div className='device conteiner-cl' onClick={() => changeState()}>
<img src={state == 1 ? image.lamp_on : image.lamp_off} alt={name} className='icon' />
{
name
}
</div>
)
}
export default Device
The api response
{
"status": "ok",
"data": [
{
"_id": "619e17af1479f1846c8afaee",
"name": "dev1",
"ip": "192.168.0.50",
"descr": "denkovi",
"channel": "",
"type": "denkovi",
"out": [
{"id": 1,"name": "output1","value": "0"},
{"id": 2,"name": "output2","value": "0"},
{"id": 3,"name": "output3","value": "0"},
{"id": 4,"name": "output4","value": "0"},
{"id": 5,"name": "output5","value": "0"},
{"id": 6,"name": "output6","value": "0"},
{"id": 7,"name": "output7","value": "0"},
{"id": 8,"name": "output8","value": "0"},
{"id": 9,"name": "output9","value": "0"},
{"id": 10,"name": "output10","value": "0"},
{"id": 11,"name": "output11","value": "0"},
{"id": 12,"name": "output12","value": "0"},
{"id": 13,"name": "output13","value": "0"},
{"id": 14,"name": "output14","value": "0"},
{"id": 15,"name": "output15","value": "0"},
{"id": 16,"name": "output16","value": "0"}
]
},
{
"_id": "619e17af1479f1846c8afaef",
"name": "dev2",
"ip": "192.168.0.50",
"descr": "denkovi",
"channel": "",
"type": "denkovi",
"out": [
{"id": 1,"name": "output1","value": "0"},
{"id": 2,"name": "output2","value": "0"},
{"id": 3,"name": "output3","value": "0"},
{"id": 4,"name": "output4","value": "0"},
{"id": 5,"name": "output5","value": "0"},
{"id": 6,"name": "output6","value": "0"},
{"id": 7,"name": "output7","value": "0"},
{"id": 8,"name": "output8","value": "0"},
{"id": 9,"name": "output9","value": "0"},
{"id": 10,"name": "output10","value": "0"},
{"id": 11,"name": "output11","value": "0"},
{"id": 12,"name": "output12","value": "0"},
{"id": 13,"name": "output13","value": "0"},
{"id": 14,"name": "output14","value": "0"},
{"id": 15,"name": "output15","value": "0"},
{"id": 16,"name": "output16","value": "0"}
]
}
]
}