Error: Objects are not valid as a React child (found: object with keys {}). use an array instead

Viewed 794

I am passing the form value to the myDoc component but it showing Object are not valid as a React child, I am Beginner in React Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.

import React,{useState} from 'react'
import {
  PDFDownloadLink,
  Page,
  Text,
  View,
  Document,
  StyleSheet,
} from '@react-pdf/renderer'

const styles = StyleSheet.create({
  page: {
    flexDirection: 'row',
    backgroundColor: '#E4E4E4',
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1,
  },
}) 

MyDoc Component

const MyDoc = (name) => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>{name}</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
) 

Edit Component


const Edit = () => {

    const [name, setName] = useState('')
  const [email, setEmail] = useState('')
  const [about, setAbout] = useState('')

  return (
    <div className="EditScreen">
      <form>
        <input
          type="text"
          value={name}
          placeholder="Name"
          onChange={(e) => setName(e.target.value)}
        ></input>
        <br></br>
        <input
          type="text"
          value={email}
          placeholder="Name"
          onChange={(e) => setEmail(e.target.value)}
        ></input>
        <br></br>
        <input
          type="text"
          value={about}
          placeholder="Name"
          onChange={(e) => setAbout(e.target.value)}
        ></input>
        <br></br>
        <button type="submit">Submit</button>
      </form>

Passing Name prop here

      <PDFDownloadLink document={<MyDoc name={name} />} fileName="somename.pdf">
        {({ blob, url, loading, error }) =>
          loading ? 'Loading document...' : 'Download now!'
        }
      </PDFDownloadLink>
    </div>
  )
}

export default Edit ```
2 Answers

React will pass a props object to your component so you need to destructure it to get the individual properties out. So change your code to:

const MyDoc = ({name}) => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>{name}</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
) 

Note the const MyDoc = ({name}) => ( part.

Another way to do this would be to...

const MyDoc = (props) => (
...

And then access the name prop like so:

<Text>{props.name}</Text>

Stringify that Object

This might not be the answer to this particular issue posted here but is related (same error message).

In my case, I was displaying my state in two places: one as raw JSON data and also as a table where the properties of the JSON were rows of name/value pairs.

The issue was that when I implemented the table view portion, I forgot to modify the raw JSON display.

Before I implemented the table, I was setting the state like this: setMyData(JSON.stringify(jsonData, null, 2))

Then I replaced that with (after I transform the jsonData above to an array): setMyData(propsArray)

Meanwhile, I was still displaying the original myData state like this: <pre>{myData}</pre>

...which means it was trying to render the Array object whereas before, it was just rendering the JSON stringified because I stringified it before I set it.

So after many hours of troubleshooting the wrong thing, I realized I just need to stringify that object (the new Array of properties) like this: <pre>{JSON.stringify(myData, null, 2)}</pre>

... which is what I was doing before (stringifying before I set the state). Not the first time I've done this but hoping by posting this it will be my last and hopefully yours, too.

Related