Skip to content

TableView not properly rendering when Rows are added or removed to/from TableBody #3463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
greenpixels opened this issue Aug 31, 2022 · 2 comments

Comments

@greenpixels
Copy link

🐛 Bug Report

When using useState(), adding or removing rows does not properly update TableView to adjust its height.
More apparant with dark-mode.

🤔 Expected Behavior

When adding or removing a row to/from TableBody, TableView should automatically adjust its height (if no height was set) to match its content.

😯 Current Behavior

When adding or removing a row, TableView does NOT increase its height. It keeps its height and adds a scrollbar. (see image)

image

Please note: In my example I have NOT set the height property.

When removing a child, TableView doe NOT decrease its height, but keeps the current height and removes a row. (see image)

image

When reloading the page with an increased amount of rows, the TableView DOES render properly with an adjusted height.
When reloading the page with a decreased amount of rows, the TableView DOES render properly with an adjusted height.

💁 Temporary Solution

Using Array.toString() for the key-property of TableView does re-render the component properly. Using Array.length for the key-property of TableView does re-render the component properly. All of that, of course, is really hacky.

🔦 Context

I am trying to create a panel in which an admin can use buttons to create, delete and edit users. When doing so, I make a call to my server to fetch users and refresh my useState of the current available users. To trigger useState's re-render I spread my array to create a new reference: setAccounts([...data]);

💻 Code Sample

Here is a stackblitz application to show you the problem:
Code (View App.tsx)
Demo
Note: Please emulate dark-mode to make the problem more apparent
Note: In this stackblitz example, adding rows doesn't seem to be a problem. In my project, adding rows does not work, (code below)

This is my code where I noticed the problem. The problem is even more apparent on here because stackblitz seems to be able to increase the component height.

import { View, TableView, Cell, Column, Row, TableBody, TableHeader, Button, DialogContainer, AlertDialog} from '@adobe/react-spectrum'
import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom';
import ActionButton from '../components/ActionButton';
import { useAuthenticated } from '../hooks/useAuthenticated'
import { ServersService } from '../services/ServerService';

export default function AdminPanel() {

  let navigate = useNavigate();
  let [authenticated, isAdmin] = useAuthenticated(() => navigate("/"));
  let [accounts, setAccounts] = useState<{ username: string, role: string, id: string }[]>([]);
  let [isOpen, setIsOpen] = useState(false);
  let [alertCallback, setAlertCallback] = useState<Function>(() => {});

  useEffect(() => {
    loadAccounts()
  }, [])

  if (!authenticated && !isAdmin) return <></>
  console.log("Re-Render");
  return (
    <View padding={{ base: "size-100", L: "size-1000", M: "size-500", S: "size-200" }}>
      <Button variant={"cta"} marginBottom="size-100">Create User</Button>
      <Button variant={"primary"} marginBottom="size-100" onPress={loadAccounts}>Reload</Button>
      <TableView
        aria-label="Example table with static contents"
        selectionMode="none"
      >
        <TableHeader>
          <Column>Name</Column>
          <Column>ID</Column>
          <Column>ROLE</Column>
          <Column align="end">ACTIONS</Column>
        </TableHeader>
        <TableBody>
        {accounts.map(account => <Row key={account.id}>
            <Cell>{account.username}</Cell>
            <Cell>{account.id}</Cell>
            <Cell>{account.role}</Cell>
            <Cell>
              <ActionButton items={[
                {
                  name: "Delete", action: () => {
                    setIsOpen(true);
                    setAlertCallback(() => () => ServersService.deleteUser(account.id).then(() => loadAccounts()))
                  }
                }
              ]} />
            </Cell>
          </Row>)}
        </TableBody>
      </TableView>
      <DialogContainer onDismiss={() => setIsOpen(false)}>
        {isOpen &&
          <AlertDialog onPrimaryAction={() => {alertCallback()}}
            title="Delete"
            variant="destructive"
            primaryActionLabel="Delete">
            Are you sure you want to delete this item?
          </AlertDialog>
        }
      </DialogContainer>
    </View>
  )

  async function loadAccounts() {
    ServersService.getAllUsers().then(response => response.json()).then((data : Array<any>) => {
      setAccounts([...data]);
    })
  }
}

🌍 Your Environment

Software Version(s)
@adobe/react-spectrum ^3.20.0
Chrome Version 104.0.5112.102
Operating System Windows 11
@Tylopilus
Copy link

This is due to StrictMode. React Spectrum really does not play well with StrictMode since a long time.

Here is a fork with StrictMode removed:
https://stackblitz.com/edit/react-ts-zjevyj?file=index.tsx

@LFDanLu
Copy link
Member

LFDanLu commented Sep 7, 2022

Closing in favor of the umbrella issue: #779

@LFDanLu LFDanLu closed this as completed Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants