ui-components icon indicating copy to clipboard operation
ui-components copied to clipboard

Inner content doesn't render if loaded with a delay

Open chrisolsen opened this issue 1 year ago • 2 comments

It was found that child content is not being rendered for some of the components1 if the child content is loaded in with a delay.

This may be a Svelte 4 issue, since things were working in <= 4.18.1

Peek 2024-04-08 09-50

  1. So for the issue has been tested and replicated using the GoABlock, GoAGrid and GoAContainer components.
import { GoABlock, GoAButton, GoACircularProgress, GoAContainer, GoAGrid } from "@abgov/react-components";
import { useEffect, useState } from "react";

type User = {
  firstName: string;
  lastName: string;
  age: number;
}

export function BlankPage() {
  const [users, setUsers] = useState<User[] | null>(null)

  useEffect(loadUsers, [])

  function reloadUsers() {
    setUsers(null);
    loadUsers();
  }

  function loadUsers() {
    setTimeout(() => {
      setUsers([
        {firstName: "Jim", lastName: "Smith", age: 23},
        {firstName: "Larry", lastName: "Lloyd", age: 34},
        {firstName: "Andy", lastName: "Anderson", age: 32},
        {firstName: "Sam", lastName: "Black", age: 54},
      ])  
    }, 2000)
  }
  
  return (
    <>
      <GoACircularProgress variant="fullscreen" size="large" message="Loading..." visible={!users}></GoACircularProgress>

      <h4>No wrapping container</h4>
      {users?.map(user => 
        <GoAContainer>
          <User user={user} />
        </GoAContainer>
      )}
      
      <h4>Container</h4>
      <GoAContainer>  
        {users?.map(user => 
          <GoAContainer>
            <User user={user} />
          </GoAContainer>
        )}
      </GoAContainer>

      <h4>Block</h4>
      <GoABlock direction="row">  
        {users?.map(user => 
          <GoAContainer>
            <User user={user} />
          </GoAContainer>
        )}
      </GoABlock>

      <h4>Grid</h4>
      <GoAGrid minChildWidth="10ch">  
        {users?.map(user => 
          <GoAContainer>
            <User user={user} />
          </GoAContainer>
        )}
      </GoAGrid>

      <h4>Grid with no container</h4>
      <GoAGrid minChildWidth="10ch">  
        {users?.map(user => 
          <User user={user} />
        )}
      </GoAGrid>
     
      <h4>Grid with raw data</h4>
      <GoAGrid minChildWidth="10ch">  
        {users?.map(user => 
          <GoAContainer>
            {user.firstName} {user.lastName}
          </GoAContainer>
        )}
      </GoAGrid>

      <GoAButton onClick={() => reloadUsers()}>Reload</GoAButton>
    </>
  )
}

type UserProps = {
  user: User
}

function User({user}: UserProps): JSX.Element {
  const [ready, setReady] = useState<boolean>(false);

  useEffect(() => {
    setTimeout(() => {
      setReady(true)  
    }, Math.random() * 3 * 1000)  
  }, [])

  if (!ready) {
    return <>Loading..</>;
  }
  
  return <>
    <div>{user.firstName} {user.lastName}</div>
    <div>Age: {user.age}</div>
  </>  
}

chrisolsen avatar Apr 08 '24 15:04 chrisolsen

Closing as it is no longer an issue according to @chrisolsen

ArakTaiRoth avatar Apr 09 '24 18:04 ArakTaiRoth

Team has noticed other related issues, we will re-open the original issue.

Spark450 avatar Apr 11 '24 17:04 Spark450

This issue still remains for wrapping like elements (Container, Block, etc), and other than the hacky solution, at the current time there doesn't seem to be a way around this. I believe it was mentioned the first time this came up in that in most cases there is some static content within the components, which will fix this issue; which is why adding a <span /> element to the content is an easy way to fix this issue.

chrisolsen avatar May 24 '24 19:05 chrisolsen