'What is the ideal way to use subscription with react apollo GraphQL
I am working on a react project which uses GraphQl for API integration, which I did perfectly. Now I am working on a module where I need to use subscription.
What I am doing
- I have charts to show one UI, which I have created successfully using ReCharts.
- So initially I a getting data from query and displaying it on UI which works totally fine.
- Than as per requirement There is some live data which I am getting through subscription i.e web socket
- So what I am doing is I stored query data in a state and when I got the live data I am appending the live data to that state and UI is updating correctly.
Issue I am facing
As I have many charts on UI so I am conditionally checking for which chart I am getting data and than appending to the particular one.
But what happens is when I got a lot of data which is coming every 2-6 seconds it hangs the browser after sometime, like after 10 minutes or 15 minutes, which is bit frustrating.
I don't know What is wrong in this, may be my approach is not good or something else
My code what I did
// below query is for getting list of factoories
//const { loading: loadingFactoryy, data: factoryList } = useQuery( FACTORYLIST);
// from above query I ll get data like below state
// as I am not connected to backend so I am taking data statically
const [factoryList, setFactoryList] = useState([
{
factoryId: 16,
factoryName: "factory one",
__typename: "user_factoryNames"
},
{
factoryId: 17,
factoryName: "factory two",
__typename: "user_factoryNames"
},
{
factoryId: 18,
factoryName: "factory Three",
__typename: "user_factoryNames"
},
{
factoryId: 19,
factoryName: "factory four",
__typename: "user_factoryNames"
}
]);
My Machine code
// below query to get the machines for each factories, if i click on
//factoryone it will give me all machines of factory one
// const [
// getMachines,
// { loading: loadingMachines, data: machineData },
// ] = useLazyQuery(FACTORYMACHINEBYID);
//I am using lazyquery so when I click I ll get the data
// useEffect(() => { this will run when page loades first time
// if (factoryList !== undefined) {
// if (factoryList.getUserFactorydNames.length > 0) {
// getInitialDataFun({
// variables: {
// factoryId:
// factoryList?.getUserFactorydNames[parseInt(activeDashboard)]
// ?.factoryId,
// },
// });
// }
// }
// }, [active_tab, factoryId, getInitialDataFun]);
//all functions for factories click
let active_tab = localStorage.getItem("active_tab") || 0;
const [active_menu, setActive_menu] = useState(Number(active_tab));
const [machineList, setmachineList] = useState([
{
chartId: 12,
chartBame: "machine1",
data: [
{
dValue: 5,
dName: "Data1"
},
{
dValue: 10,
dName: "Data2"
}
]
},
{
chartId: 13,
chartBame: "machine2",
data: [
{
dValue: 5,
dName: "Data1"
},
{
dValue: 10,
dName: "Data2"
}
]
}
]);
My subscription code
// my subscription code
// const {
// data: LiveDataMachine,
// error: errorLiveDataMachine,
// } = useSubscription(LIVEDATAMACHINEFUN, {
// variables: { topic: { topic: 'livemessage/' } },
// });
const factoryClick = (li, ind) => {
setActive_menu(ind);
localStorage.setItem("active_tab", ind);
};
//My live data looks like below
// {
// "chartId": 16,
// "chartBame": "machine1",
// "data": [
// {
// "dValue": 7,
// "dName": "Data1"
// },
// {
// "dValue": 18,
// "dName": "Data2"
// }
// ]
// }
// So what I am doing is whenever I am getting the live data
//I am looping it with main machine data and checking for chartId
//once it matches I am appending the data like below
// useEffect(() => {
// if(machineList){
// machineData.map((li,ind)=>{
// if(LiveDataMachine.chartId===li.chartId){
// setmachineList(machineList=>[...machineList,LiveDataMachine])
// }
// })
// }
// }, [LiveDataMachine]);
// but what is hapenning is it is updating the UI so fast that my browser is getting hanged
return (
<div className="App">
<FactoryComp
factoryData={factoryList}
active_menu={active_menu}
factoryClick={factoryClick}
/>
<hr />
<MachinesComp machineData={machineList} />
</div>
above is how I am writing my code and managing GraphQl subscription, I don't know what I am doing wrong which is making my browser hangs alot here I am looking for a correct approach by which I can use subscription with my query.
Here is my working code I have written everything as a comment for better uderstanding
Solution 1:[1]
Looks like you are calling setmachineList in the if inside a render. It will endlessly cause component updates, thereby cycling it. Perhaps it is better to move this logic to useEffect?
useEffect(() => {
if(machineList){
machineData.forEach((li,ind)=>{
if(LiveDataMachine.chartId===li.chartId){
setmachineList(machineList=>[...machineList,LiveDataMachine])
}
})
}
}, [LiveDataMachine]);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Валера БитковÑкий |
