0

this is my first question on here so I hope I am doing this right. I am working on a trivia game using React and the API Open Trivia Database. I made two separate pages for the components Questions and Categories but I can't figure out how to get them onto the main page... and frankly where to go from there. Thank you for your time.

Here is my main page:

import React from 'react'
import './App.css'
// import axios from 'axios'
import Questions from './components/questions'
import Categories from './components/categories'

class App extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      questions: [],
      categories: []
      // score: 0,

    }
  }

  render () {
    return (
      <div className='App'>
        <h2>Trivia Game</h2>
        {this.state.Questions}

      </div>
    )
  }
}
export default App

and here is the Question page:

import React from 'react'
import axios from 'axios'

class Questions extends React.Component {
  constructor () {
    super()
    this.state = {
      questions: []

    }
  }

  componentDidMount () {
    axios
      .get('https://opentdb.com/api.php?amount=10')
      .then(response => {
        console.log(response.data)
        this.setState({
          questions: response.data.results
        })
      })
  }

  componentWillUnmount () {
    console.log('componentDidUnmount')
  }

  render () {
    return (
      <div className='Questions'>
        <h2>Questions</h2>
        <ul>
          {this.state.questions.map((question, index) => (
            <li key={index}>{question.question}</li>
          ))}
        </ul>
      </div>
    )
  }
}
export default Questions

3 Answers3

1

It looks like you're importing your Questions and Categories components to the App.js file but you're not rendering them.

Your return statement should look like so:

    return (
      <div className='App'>
        <h2>Trivia Game</h2>
         <Questions questions={this.state.questions} />
         <Categories categories={this.state.categories}/>

      </div>
    )

You'll also want to pass your app slice of state to the respective components. I noticed that you have questions array in the App state and the Questions state. Usually you should try to avoid duplicating state and keep it at the highest needed component, in this case it looks to be App.js

Hyetigran
  • 1,150
  • 3
  • 11
  • 29
  • Thank you so much!! This is great!! – Sloths Are Great Jun 24 '20 at 00:57
  • I have a follow up question if you don't mind... when the questions come up on the page and there is a quote involved it shows up like this ""Lord of the Flies"" for example.... Is that something to do with the URL from the API or how it's passed in? Some formatting problem? – Sloths Are Great Jun 24 '20 at 01:19
  • I would console.log the data as soon as you receive it from the API to see if that's how you're getting it or that's how your client/browser is displaying it. One thing that could be happening is that your client might mistake an apostrophe for the ending of the quote i.e. 'Hello World's'. In that case you can 1) escape it by adding a \ before the apostrophe, 2) surround the string with double quotes 3) surround the string with backticks i.e. ` – Hyetigran Jun 24 '20 at 04:55
0

You've already imported them in your main page, now you just have to plug them in:

render () {
    return (
      <div className='App'>
        <h2>Trivia Game</h2>
        //   {this.state.Questions}   not sure what you wanted to do with this
        <Categories />
        <Questions />
      </div>
    )
  }

You can also pass props to each of them by adding an attribute afterwards...see here

Bender
  • 109
  • 7
  • Yes I am not sure what I was trying to do there haha, just throwing things against the wall to see if they stick. Thank you so much for your help!! – Sloths Are Great Jun 24 '20 at 00:50
0

This generally looks good, but I think you could probably use more research on how to use state and props in React.

Your component and component both work perfectly, you just need to learn to sync them up. Right now, there isn't any interaction between the two so there is no need for a constructor in either file and, at least for now, I would keep anything with "questions" out of the state in the main component- let the Questions component do the heavy lifting there.

To simplify the code, your main page can look like this:

import React from 'react'
import './App.css'
import Questions from './Questions'

class App extends React.Component {
  render () {
    return (
      <div className='App'>
        <h2>Trivia Game</h2>
        <Questions/>
      </div>
    )
  }
}

And the Questions file can remain the same, except with a quick simplification to the constructor function

import React from 'react'
import axios from 'axios'

class Questions extends React.Component {
    state = {
      questions: []
    }

  componentDidMount () {
    axios
      .get('https://opentdb.com/api.php?amount=10')
      .then(response => {
        console.log(response.data)
        this.setState({
          questions: response.data.results
        })
      })
  }

  componentWillUnmount () {
    console.log('componentDidUnmount')
  }

  render () {
    return (
      <div className='Questions'>
        <h2>Questions</h2>
        <ul>
          {this.state.questions.map((question, index) => (
            <li key={index}>{question.question}</li>
          ))}
        </ul>
      </div>
    )
  }
}
export default Questions

As your code gets more complex, you might need to add in a constructor to pass props and have these functions components interact, but it's probably best to build up to that and start as simple as possible.

iamjane
  • 162
  • 8