I have this very minimal app. It consist of one input element and a table. When pressing on a cell in the table, the input element shows what cell was pressed in the table.
However, I noticed that it takes surprisingly long (0.3s) to show the selected cell in the input element. I then did some profiling, and console.logging, and this was the output:
I’m still very much a beginner in React, and would like to know what design patterns I’m overseeing for functionality like this. I don’t understand why the entire app is re-rendered (at least in the virtual DOM), even though only a small section of it (the <ShowSelectedCell/>
) should change.
Minimal example:
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Tooltip, TextField } from '@mui/material';
import { useState } from 'react'
const ShowSelectedCell = ({ cell }) => {
return (
<TextField disabled value={cell} />
);
}
const SelectCell = ({ cells, onCellClick }) => {
return (
<table >
<tbody>
{console.log('rendering SelectCell')}
{cells.map(function (template_name, r) {
return (
<tr key={r}>
{template_name.map(function (item, c) {
return (
<Tooltip disableInteractive key={`${r} ${c} tooltip`} title={`${r} ${c}`} placement="bottom-start">
<td style={{ "border": "solid" }}
onClick={() => { onCellClick(r, c) }}
key={`${r} ${c} button`}>
{`${r} ${c}`}
</td>
</Tooltip>
);
})}
</tr>
);
})}
</tbody>
</table>
);
}
const App = () => {
const [cells, setCells] = useState(Array(30).fill().map(() => Array(25).fill(null)))
const [cell, setCell] = useState('')
const onCellClick = (r, c) => {
setCell([r, c])
console.log(`${r}, ${c}`)
}
return (
<div className='container'>
{console.log('rerendering app')}
<ShowSelectedCell cell={cell} />
<SelectCell onCellClick={onCellClick} cells={cells} />
</div>
)
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>