0

I've done a bit of research on the issue and I see the main cause is from trying to initialize a state inside of a conditional statement. So I've gone ahead and confirmed that was not my issue. I found the state causing the issue and it is inside a function I am using to generate a table. I read that it's possible that the state generated inside of a map could cause the error but I'm not sure why since I don't call it conditionally.

Is it possible it could be caused by my async useEffect inside of FileDirectoryBody?

Error

   Previous render            Next render
   ------------------------------------------------------
1. useState                   useState
2. useEffect                  useEffect
3. useEffect                  useEffect
4. undefined                  useState

FileDirectory: Top level

export default function FileDirectory(){

  return(
      <div>
        <Header/>
        <FileDirectoryBody/>
      </div>
   )
}

FileDirectoryBody:

export default function FileDirectoryBody(){

    const[files,setFiles] = useState([])

    useEffect(()=>{ // Testing
        console.log('files updated')
        console.log(files)
    },[files])

    useEffect(async()=>{
        setFiles(sortByFamily(await getAllFiles()))
    },[])

    return(
        <div class='family-file-container'>
            <FamilyTable sortedFiles={files}/>
        </div>
    );
}

FamilyTable:

export default function FamilyTable(props){

    const[sortedFiles,setSortedFiles] = useState([])

    useEffect(()=>{
        setSortedFiles(props.sortedFiles)
    },[props.sortedFiles])

    useEffect(()=>{ // Testing
        console.log('sorted Files updated')
        console.log(sortedFiles)
    },[sortedFiles])

    const generateRows = () =>{ // Maps rows of files and their meta data

        return(
            sortedFiles.map((family,index)=>{
                return(
                    generateFamilyRow(family) 
                )
            })
        )

    }

    return(
        <div>
            <div class='file-directory-header'>
                <h1 class='header-text'>File Directory</h1>
            </div>
            <div class='column-row'>
                <div class='header-column-row-text'>Family Name</div>
                <div class='header-column-row-text'>Cell Count</div>
                <div class='header-column-row-text'>Expand Family</div>
            </div>
            <Line color={'black'}/>
            <div class='directory-body'>
                {generateRows()}
            </div>
        </div>
    );

}

generateFamilyRow: The issue is here

export default function GenerateFamilyRow(family){

    const[open,setOpen] = useState([]) // State that is causing the issue
    const toggle = () =>{setOpen(!open)}

    return(
        <div>
            <div class='family-row'>
                <div class='family-row-item'>{family[0].family_name}</div>
                <div class='family-row-item'>{family.length}</div>
                <div class='family-row-item'><button onClick={()=>{toggle()}}>{open ? '^' : '⌄'}</button></div>
                <Line color={'black'}/>
            </div>
            {open && <table class='family-table' id={`family-table-${family.family_name}`}>
                <tr>
                    <th>File Name</th>
                    <th>Cell ID</th>
                    <th>Cell Powder ID</th>
                    <th>Cell Family Name</th>
                    <th>Cell Last Uploaded</th>
                </tr>
            </table>}    
        </div>
    );

}
danronmoon
  • 3,814
  • 5
  • 34
  • 56
  • 1
    `GenerateFamilyRow` is neither a component nor a hook, you shouldn't be using hooks in it. If the length of the array changes, the number of `useState` calls within `FamilyTable`'s context changes. Turn on [the linting](https://legacy.reactjs.org/docs/hooks-rules.html#eslint-plugin), follow the rules. – jonrsharpe Apr 05 '23 at 21:21
  • @jonrsharpe Sorry, I'm still learning. Are you saying that the open state isn't used till after the array changes and that causes the change in the number of states? – boredProjects Apr 06 '23 at 03:45

1 Answers1

0
  1. The code that you have provided can't be right, because the component is upper case GenerateFamilyRow, and the function you are calling is lower case generateFamilyRow.

  2. The sortByFamily and the async function might cause problems as well (you haven't shown the code). See also: how-to-call-an-async-function-inside-a-useeffect-in-react.

  3. Hooks are only allowed inside components, not other functions. See the Rules of Hooks.

  4. The component GenerateFamilyRow with the useState hook might work if you call it as a component, like:

sortedFiles.map( (family, index) => {
    return(
        <GenerateFamilyRow family={ family } />
    );
})

kca
  • 4,856
  • 1
  • 20
  • 41