Mark Hayden
Mark Hayden

Reputation: 103

React JS Child objects not showing as valid

I know this is a repeat question but I'm sorry, I can't find an answer. I'm trying to import data into a React/Redux Quiz Component, but i'm getting the error

Uncaught Error: Objects are not valid as a React child (found: object with keys {answer, text}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Quiz.

Here's my data file:

export const exampleQuestions = [
  {
    Question: 1,
    type: 'example',
    set: 1,
    text: 'Which one is true?',
    answers:
    [
      {
        answer: 'A',
        text: 'sometext',
      },
      {
        answer: 'B',
        text: 'sometext',
      },
      {
        answer: 'C',
        text: 'Neither of the above'
      }
    ]
  },
  {
    Question: 2,
    type: 'example',
    set: 1,
    text: 'Which one is true?',
    answers:
    [
      {
        answer: 'A',
        text: 'Sometext',
      },
      {
        answer: 'B',
        text: 'sometext',
      },
      {
        answer: 'C',
        text: 'Neither of the above'
      }
    ]
  },
  {
    Question: 3,
    type: 'example',
    set: 1,
    text: 'Which one is true?',
    answers:
    [
      {
        Answer: 'A',
        text: 'Sometext',
      },
      {
        Answer: 'B',
        text: 'sometext',
      },
      {
        Answer: 'C',
        text: 'Neither of the above'
      }
    ]
  },
  {
    Question: 4,
    type: 'example',
    set: 1,
    text: 'Which one is true?',
    answers:
    [
      {
        Answer: 'A',
        text: 'sometext',
      },
      {
        Answer: 'B',
        text: 'sometext'
      },
      {
        Answer: 'C',
        text: 'Neither of the above'
      }
    ]
  }
]

And here's my Quiz component:

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { chunk, now } from '../utils'

class Quiz extends Component {
  constructor(props) {
    super(props)
    this.state = {
      answers: new Array(this.props.question).fill('e'),
      chosenAnswers: []
    }
  }

  onAnswerSelected() {
    let answers = [this.state.answers]
    answers[qindex] = String.fromCharCode(97 + i)
    this.setState({ ...state,answers })

  }

  render() {
    const { set, enterAnswers, id, timed, questions } = this.props
    console.log(questions);
    const { qindex, text, answers } = questions

    return (
      <div>
          <div key={qindex}>
            <h4>{text}</h4>
            {answers.map((a, i) => (
              <label key={i} style={{ display: 'block' }}>
                <input
                  type="radio"
                  id={`${qindex}_${i}`}
                  checked={
                    this.state.answers[qindex] === String.fromCharCode(97 + i)
                  }
                  onChange={this.onAnswerSelected.bind}
                  value={String.fromCharCode(97 + i)}
                />
                &nbsp;{a}
              </label>
            ))}
          </div>
        <div
          className="button"
          onClick={() => enterAnswers(id, this.state.selected, now())}
          style={{
            border: '1px solid black',
            backgroundColor: 'purple',
            display: 'inline-block',
            color: 'white',
            padding: 10
          }}
        >
          Save answers
        </div>
      </div>
    )
  }
}

Quiz.propTypes = {
  set: PropTypes.array,
  enterAnswers: PropTypes.func,
  id: PropTypes.number,
  timed: PropTypes.number
}

export default Quiz

What am I doing wrong?

Upvotes: 1

Views: 753

Answers (3)

Kalaikumar Thangasamy
Kalaikumar Thangasamy

Reputation: 564

try this, I hope this will work.

render() {
    const { set, enterAnswers, id, timed, questions } = this.props
    console.log(questions);
    const { qindex, text, answers } = questions

    return ( 
        <div>
           { this.questions() }
        </div>
        );
}

questions() {
 return questions.map((question) =>{
    return (
       <div key={question.Question}>
            <h4>{question.text}</h4>
            { this.answer(question.answers) }
        </div>
        <div
            className="button"
            onClick={() => enterAnswers(id, this.state.selected, now())}
            style={{
                border: '1px solid black',
                backgroundColor: 'purple',
                display: 'inline-block',
                color: 'white',
                 padding: 10
            }}
            >
             Save answers
        </div>
    );
 });
}

answer(answer) {
   return answer.map((a, i) =>{
     return (
        <label key={i} style={{ display: 'block' }}>
        <input
          type="radio"
          id={`${qindex}_${i}`}
          checked={
            this.state.answers[qindex] === String.fromCharCode(97 + i)
          }
          onChange={this.onAnswerSelected.bind}
          value={String.fromCharCode(97 + i)}
        />
        &nbsp;{a.text}
       </label>
     );
   });


}

Upvotes: 0

croraf
croraf

Reputation: 4720

You are trying to render an object a at this part of the code:

answers.map((a, i) => (
              <label key={i} style={{ display: 'block' }}>
                <input
                  type="radio"
                  id={`${qindex}_${i}`}
                  checked={
                    this.state.answers[qindex] === String.fromCharCode(97 + i)
                  }
                  onChange={this.onAnswerSelected.bind}
                  value={String.fromCharCode(97 + i)}
                />
                &nbsp;{a}   <----- the erroneous part
              </label>
        ))

As error note says, objects cannot be rendered as such. This object contains answer and text fields. You should render each of those properties separately instead of rendering the object itself. For example you can do:

answers.map((a, i) => (
              <label key={i} style={{ display: 'block' }}>
                <input
                  type="radio"
                  id={`${qindex}_${i}`}
                  checked={
                    this.state.answers[qindex] === String.fromCharCode(97 + i)
                  }
                  onChange={this.onAnswerSelected.bind}
                  value={String.fromCharCode(97 + i)}
                />
                <div>{a.answer}, {a.text}</div>
              </label>
        ))

Upvotes: 2

shanmukha rao G
shanmukha rao G

Reputation: 1

Try assigning the answers.map to a variable outside return.

Upvotes: 0

Related Questions