Recharts slow rendering issue - reactjs

import React, { useState, useEffect } from "react";
import './App.css';
import {
Line,
LineChart,
XAxis,
YAxis,
} from 'recharts';
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://localhost:4001";
function App() {
const [data, updateData] = useState([]);
const socket = socketIOClient(ENDPOINT, {
transports: ['websocket', 'polling']
});
useEffect(() => {
socket.on("a", a => {
updateData(currentData => [...currentData, a])
});
}, []);
if(data.length>200)
{
updateData(data.shift())
}
return (
<div className="App">
<h1>size of data is :- {data.length}</h1>
<LineChart width={1000} height={500} data={data}>
<XAxis dataKey="name" />
<YAxis />
<Line dataKey="value" />
</LineChart>
</div>
);
}
export default App;
This is my code I am getting maximum of 200 data per second from socket.io .Code is working fine but as some time passes it start lagging , graph rendering becomes slow .
can any one please tell how can I fix it or optimize it .

There is an anti pattern here, you are calling data.shift() which directly modifies the state, which is a no no.
The other issue is your length check is outside the useEffect.
Instead, use Array.slice() like this:
import React, { useState, useEffect, useMemo } from 'react';
import './App.css';
import { Line, LineChart, XAxis, YAxis } from 'recharts';
import socketIOClient from 'socket.io-client';
const ENDPOINT = 'http://localhost:4001';
function App() {
const [data, updateData] = useState([]);
const socket = socketIOClient(ENDPOINT, {
transports: ['websocket', 'polling'],
});
useEffect(() => {
socket.on('a', (a) => {
updateData((currentData) => {
const a = [...currentData, a];
return a.length <= 200 ? a : a.splice(1);
});
});
}, []);
const graph = useMemo(() => {
return (
<LineChart width={1000} height={500} data={data}>
<XAxis dataKey='name' />
<YAxis />
<Line dataKey='value' />
</LineChart>
)
}, [data]);
return (
<div className='App'>
<h1>size of data is :- {data.length}</h1>
{graph}
</div>
);
}
export default App;

Related

How to add mouse events to each mesh part loaded from Rhino3dm file in React-Three-Fiber?

I want to realize a function that changes color when the mouse is over each mesh part loaded from an Rhino3dm file with react-three-fiber.But in the code below mouse events are not working properly for some reason.
For GLTF, using Object.values(gltf.nodes).map worked fine.
enter image description here
For Rhino3dm, I use object.children.map and I think this is bad.
Do you know the cause and solution?
This is the sandbox URL.
https://codesandbox.io/s/test-rhino3dmloader-wnrty6?file=/src/App.js
import "./styles.css";
import * as THREE from "three";
import { useEffect, useMemo, useRef, useState } from "react";
import { Canvas } from "#react-three/fiber";
import { useLoader } from "#react-three/fiber";
import { Rhino3dmLoader } from "three/examples/jsm/loaders/3DMLoader";
import { Environment, OrbitControls} from "#react-three/drei";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { Suspense } from "react";
const Part = (child) => {
const objRef = useRef();
const [hovered, setHover] = useState(false);
const material = new THREE.MeshStandardMaterial({
color: hovered ? "hotpink" : "orange"
});
return (
<mesh
key={child.id}
ref={objRef}
castShadow
receiveShadow
onPointerOver={(e) => {
e.stopPropagation();
setHover(true);
}}
onPointerOut={(e) => {
e.stopPropagation();
setHover(false);
}}
>
<primitive object={child} material={material} />
</mesh>
);
};
const Model = () => {
// For some reason mouse events don't work well in Rhino3dm.
const object = useLoader(Rhino3dmLoader, "./rhino_logo.3dm", (loader) => {
loader.setLibraryPath("https://cdn.jsdelivr.net/npm/rhino3dm#0.15.0-beta/");
});
const model = object.children.map((child) => Part(child));
// For gltf the below code worked fine.
/* 
const gltf = useLoader(GLTFLoader, "./rhino_logo.glb");
const model = Object.values(gltf.nodes).map((child) => {
if(child.isMesh){
return Part(child)
}
});
*/
return model;
};
export default function App() {
return (
<div className="App">
<Canvas>
<Suspense fallback={null}>
<Model />
<OrbitControls />
<Environment preset="sunset" background />
</Suspense>
</Canvas>
</div>
);
}
I was able to solve it below! Thank you!!
https://discourse.threejs.org/t/how-to-add-mouse-events-to-each-mesh-part-loaded-from-rhino3dm-file-in-react-three-fiber/48191/2

React Native Error: Invalid hook call. Hooks can only be called inside of the body of a function component

I'm programming with some friends a Chess App and now we get an Error implementing the Chess itself.
we get the error in the first const of the function as well as at the Export of App.jsx
Our GitHub Repo: Chedu
App.jsx
import React, { useEffect, useState } from "react";
import "./App.css";
import { gameSubject, initGame, resetGame } from "./Game";
import Board from "./Board";
function App() {
const [board, setBoard] = useState([]); //get Error here
const [isGameOver, setIsGameOver] = useState();
const [result, setResult] = useState();
const [turn, setTurn] = useState();
useEffect(() => {
initGame();
const subscribe = gameSubject.subscribe((game) => {
setBoard(game.board);
setIsGameOver(game.isGameOver);
setResult(game.result);
setTurn(game.turn);
});
return () => subscribe.unsubscribe();
}, []);
return (
<div className="container">
{isGameOver && (
<h2 className="vertical-text">
GAME OVER
<button onClick={resetGame}>
<span className="vertical-text"> NEW GAME</span>
</button>
</h2>
)}
<div className="board-container">
<Board board={board} turn={turn} />
</div>
{result && <p className="vertical-text">{result}</p>}
</div>
);
}
export default App(); //Error Anonymous Function
in Index.js we are Rendering the function and export it.
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
export default ReactDOM.render(
<React.StrictMode>
<DndProvider backend={HTML5Backend}>
<App />
</DndProvider>
</React.StrictMode>,
document.getElementById("root")
);
serviceWorker.unregister();
And at last we want to render the index.js in our ChessBoardPage
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
Image,
TouchableOpacity,
Dimensions,
Switch,
} from "react-native"; //components
import ReactDOM from "react-dom";
import cheduLogo from "../Pictures/Logo.png";
import loginPictureBlack from "../Pictures/login.png";
import loginPictureWhite from "../Pictures/login_white.png";
import registerPictureBlack from "../Pictures/register.png";
import registerPictureWhite from "../Pictures/register_white.png";
import userPictureBlack from "../Pictures/user.png";
import userPictureWhite from "../Pictures/user_white.png";
import ChessGame from "./ChessBoard/index";
const windowWidth = Dimensions.get("window").width;
const windowHeight = Dimensions.get("window").height;
const { width } = Dimensions.get("window");
const x = 100;
const y = 200;
export default class TempPage extends React.Component {
state = {
switchValue: false,
backgroundColor: "white",
SwitchLogin: loginPictureBlack,
SwitchRegister: registerPictureBlack,
SwitchUser: userPictureBlack,
SunMoon: "☀️",
ShadowBackgroundColor: "white",
};
handleSwitchBackground = () => {
[...]
}
};
render() {
let { backgroundColor } = this.state;
return (
<View
style={{
windowWidth,
windowHeight,
backgroundColor: this.state.backgroundColor,
}}
>
[...]
{/*Content*/}
<View stlye={{ flex: 1 }}>
<ChessGame />
</View>
</View>
);
}
}
[...]
sometime we have issues in react when using anonymous functions. Since anonymous functions aren’t assigned an identifier (via const/let/var), they aren’t persistent whenever this functional component inevitably gets rendered again. This causes JavaScript to allocate new memory each time this component is re-rendered instead of allocating a single piece of memory only once when using “named functions”
consider refactoring your code as follows
import React, { useEffect, useState } from "react";
import "./App.css";
import { gameSubject, initGame, resetGame } from "./Game";
import Board from "./Board";
const App = () => {
const [board, setBoard] = useState([]); //get Error here
const [isGameOver, setIsGameOver] = useState();
const [result, setResult] = useState();
const [turn, setTurn] = useState();
useEffect(() => {
initGame();
const subscribe = gameSubject.subscribe((game) => {
setBoard(game.board);
setIsGameOver(game.isGameOver);
setResult(game.result);
setTurn(game.turn);
});
return () => subscribe.unsubscribe();
}, []);
return (
<div className="container">
{isGameOver && (
<h2 className="vertical-text">
GAME OVER
<button onClick={resetGame}>
<span className="vertical-text"> NEW GAME</span>
</button>
</h2>
)}
<div className="board-container">
<Board board={board} turn={turn} />
</div>
{result && <p className="vertical-text">{result}</p>}
</div>
);
};
export default App;
I am not sure why you are using HTML tags in react native, which think are not yet supported in App.jsx. You should return a <View/> tag instead of div.

Realtime Chart in reactjs

import React, { useState, useEffect } from 'react';
import './App.css';
import { Line, LineChart, XAxis, YAxis } from 'recharts';
import socketIOClient from 'socket.io-client';
const ENDPOINT = 'http://192.168.1.45:4001';
function App() {
const [data, updateData] = useState([]);
const socket = socketIOClient(ENDPOINT, {
transports: ['websocket', 'polling'],
});
useEffect(() => {
socket.on('a', (a) => {
updateData((currentData) => {
const ab = [...currentData, a];
return ab.length <= 200 ? ab : ab.splice(1);
});
});
}, []);
return (
<div className='App'>
<h1>size of data is :- {data.length}</h1>
<LineChart width={1000} height={500} data={data}>
<XAxis dataKey='name' />
<YAxis />
<Line dataKey='value' />
</LineChart>
</div>
);
}
export default App;
Up here is the code for real-time chart in react I am having a socket.io connection and the server is emitting at least 150 values per second. Chart is working fine on the first 60 seconds but after that, it start lagging. I can't able to pinpoint the issue here.
I asked this before also where Nick helped me achieve this result, but it's not smooth yet.
help is much appreciated

Unable to display an API data using map function on Material UI tabs

I'm new to this programming world. Can anyone please help me on this.
I have implemented Material UI's tabs successfully by hard-coding the content, but when I tried to make my hard coded tabs with a .map function to populate the content from a data source (json), it no longer works. The tab displays nothing.
Here are the codes,
Planet component:
import React from 'react';
function Planet(props) {
return (
<ul>
<li>{props.name}</li>
</ul>
);
}
export default Planet;
Planets component:
import React, { useEffect, useState} from 'react';
import Planet from './Planet';
function Planets(props) {
const [planets, setPlanets] = useState([]);
useEffect(() => {
getPlanets();
}, []);
const getPlanets = async () => {
const response = await fetch("https://assignment-machstatz.herokuapp.com/planet");
const data = await response.json();
setPlanets(data);
}
return (
<div>
{planets.map((planet, index) => {
return (
<Planet key={index} name={planet.name} />
);
})}
</div>
);
}
export default Planets;
App component:
import React, { useState } from 'react';
import { AppBar, Tabs, Tab } from '#material-ui/core';
import Planet from './Planet';
import Favplanets from './Favplanets';
function App() {
const [selectedTab, setSelectedTab] = useState(0);
function handleChange (event, newValue) {
setSelectedTab(newValue);
}
return (
<>
<AppBar position="static">
<Tabs value={selectedTab} onChange={handleChange} >
<Tab label="Planets" />
<Tab label="Favourite Planets" />
</Tabs>
</AppBar>
{selectedTab === 0 && <Planet />}
{selectedTab === 1 && <Favplanets />}
</>
);
}
export default App;
Thanks for your help!

Why is the child column component of AgGridReact not rendering?

When rendering a AG grid table using external functional components for the declarative column definitions they don't get rendered. Also the columns component render is not executed when putting a breakpoint.
I have the following AG grid table component:
import React, { useState, useEffect } from 'react';
import 'ag-grid-enterprise';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { AgGridReact } from 'ag-grid-react';
import Columns from '../columns/columns';
const Table = (props) => {
const [columnDefs, setColumnDefs] = useState([]);
useEffect(() => {
fetch('/api/grid/getDataOverviewGrid')
.then((result) => {
return result.json();
})
.then((gridOverview) => {
setColumnDefs(gridOverview.data.gridColumns);
});
}, []);
return (
<div className="ag-theme-alpine">
<AgGridReact
getDataPath={(data) => data.orgHierarchie}
pagination={true}
onGridReady={(params) => {
fetch('/api/grid/getDataOverviewGridRows')
.then((result) => {
return result.json();
})
.then((rowData) => {
params.api.setRowData(rowData.data);
});
}}
>
<Columns columnDefs={columnDefs} />
</AgGridReact>
</div>
);
};
export default Table;
and the following columns component:
import React from 'react';
import { AgGridColumn } from 'ag-grid-react';
const Columns = ({ columnDefs }) => {
return (
<>
{columnDefs.map((column) => {
return (
<AgGridColumn
headerName={column.headerName}
field={column.field}
/>
);
})}
</>
);
};
export default Columns;
In the code above the columns component is not executed.
When rendering the columns directly in the table component it works and the columns are rendered.
import React, { useState, useEffect } from 'react';
import 'ag-grid-enterprise';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { AgGridReact } from 'ag-grid-react';
const Table = (props) => {
const [columnDefs, setColumnDefs] = useState([]);
useEffect(() => {
fetch('/api/grid/getDataOverviewGrid')
.then((result) => {
return result.json();
})
.then((gridOverview) => {
setColumnDefs(gridOverview.data.gridColumns);
});
}, []);
return (
<div className="ag-theme-alpine">
<AgGridReact
getDataPath={(data) => data.orgHierarchie}
pagination={true}
onGridReady={(params) => {
fetch('/api/grid/getDataOverviewGridRows')
.then((result) => {
return result.json();
})
.then((rowData) => {
params.api.setRowData(rowData.data);
});
}}
>
{columnDefs.map((column) => {
return (
<AgGridColumn
headerName={column.headerName}
field={column.field}
/>
);
})}
</AgGridReact>
</div>
);
};
export default Table;
I can't remember where I've read it - apparently not in the documentation - but if <AgGridReact /> has any children, all of them must be of <AgGridColumn />.
Wrapping them in Fragments will most likely not work. Not even nulls will do (learned that the hard way).

Resources