adobe / adobe/react-spectrum

[Table] Cell render triggers the render of the whole table

Open
#10,088 4 comments 4 reactions 0 assignees View on GitHub
Table
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

### Provide a general summary of the issue here

Hello everyone!

We are using `react-aria-components` to simplify a11y support in our application, but we have faced performance issues in our case.
We are working with trading UIs, and there are many cases where you need to show changes in the Cell very fast.
To make it cheap, we are subscribing to data in each Cell and render Cells only to avoid huge recalculations.
But, we found out that Table in `react-aria-components` conflicts with this approach.
For example, if I add the Cell like so:
```jsx
function VolatileNumericCell() {
const [value, setValue] = useState(() => Math.random())

useEffect(() => {
const id = window.setInterval(() => {
setValue(Math.random())
}, 1000)
return () => {
window.clearInterval(id)
}
}, [])

return {value.toFixed(6)}
}
```
It is just a Simple Cell, which rerenders itself every second. But, this Cell will trigger the whole table, which can be easily detected with React Dev Tools

I can fix it like so:
```jsx
function VolatileNumericCell2() {
const [value, setValue] = useState(() => Math.random())

useEffect(() => {
const id = window.setInterval(() => {
setValue(Math.random())
}, 1000)
return () => {
window.clearInterval(id)
}
}, [])

return value.toFixed(6)
}
```
And then Render like so:
```jsx

```
This approach fixes behavior, but it is not a really convenient way to work with, especially if you want to make the Cell appearance dynamic

As I understand, the problem is:
- setProps triggers queueUpdate in the document
- These changes through useSyncExternalStore trigger the whole table

### 🤔 Expected Behavior?

If Render Cell only, it renders only Cell

### 😯 Current Behavior

Any Cell renders triggers the render of the whole Table

### 💁 Possible Solution

Find out the way to update the table model (document) only in cases when it is necessary, or add some Eq or memoisation

### 🔦 Context

I am trying to create a big table with many-many cells, which updates itself by subscribing to some data outside. The table is absolutely static in this task, but the cells are very dynamic

### 🖥️ Steps to Reproduce

Create any table layout and add Cell like so:
```jsx
function VolatileNumericCell() {
const [value, setValue] = useState(() => Math.random())

useEffect(() => {
const id = window.setInterval(() => {
setValue(Math.random())
}, 1000)
return () => {
window.clearInterval(id)
}
}, [])

return {value.toFixed(6)}
}
```

[Example for storybook](https://pastebin.com/dxhZSZG7)

### Version

1.17.0

### What browsers are you seeing the problem on?

Chrome

### If other, please specify.

_No response_

### What operating system are you using?

Mac OS

### 🧢 Your Company/Team

_No response_

### 🕷 Tracking Issue

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.