Why is array.map() not a function?

Viewed 85

I want to map an array from react's useState hook, but I get the error:

TypeError: documents.map is not a function

This is my code:

const [docs, setDocs] = useState(documents);

const rows = documents.map((doc) => (
    <tr key={doc.id}>
      <td>
        <Group spacing="sm">
...

where "documents" comes from props.

I console-logged docs and it prints out an array. What am I missing here? Is it, because "docs" is a state value?

To further clarify: I fetch the documents from supabase and want to integrate a realtime subscription.

Whenever I get a change in the db, the useEffect function triggers the setState function. Then the error appears. So I am not sure how to handle this with default values.

4 Answers

If you want to map documents from useState hook, then you shouldn't map documents (since this is an initializer, not the state value). Try this:

const [docs, setDocs] = useState(documents || []);

const rows = docs.map((doc) => <tr key={doc.id}>...

I tend to agree with @zero298. It's likely at some point documents still isn't fully defined. Try using a boolean check:

const rows = !!documents && documents.map((doc) => {});

!!documents will return truthy or falsy. If falsy, rows will just equal false, otherwise your .map() will proceed.

Since documents come from props, you need to apply a condition on the render of this component in its parent, like so:

  {documents && documents.length > 0 && <Child documents={documents} />}

Or you could give the component a defaultProps for documents like this:

Component.defaultProps {
  documents:[]
}

Where Component is the name of your component.

If the documents property is from props you have to check it either it is undefined or not. It can be done if you use it inside useEffect hook. pass documents as dependency injection and add if condition when document is not undefined then you can call a function which will loop through documents using map

useEffect(() => {
if(props.documents !== undefined && props.documents.length > 0)
   {  /** Add logic here **/}
}, [props.documents])
Related