简体   繁体   中英

Rendering info from the Reddit API using React

I am trying to build a basic web app where a user can search for subreddits using the Reddit API. However, while I can console.log the data I need from the API I cannot seem to figure out how to display it.

import React, { useState, useEffect } from "react";
import Amplify, { API, graphqlOperation } from "aws-amplify";
import aws_exports from "./aws-exports";
import { withAuthenticator, AmplifySignOut }  from '@aws-amplify/ui-react';
import awsconfig from "./aws-exports";
import './App.css'
import axios from 'axios'
import CharacterGrid from './components/CharacterGrid'
import SearchBar from './components/SearchBar'

Amplify.configure(awsconfig); 

const App = () => {
 
  const [items, setItems] = useState([])
  const [isLoading, setIsLoading] = useState(true)
  const [query, setQuery] = useState('')

  useEffect(() => {
    const fetchItems = async () => {
      setIsLoading(true)
      const result = await axios(
        `https://www.reddit.com/subreddits/search.json?q=${query}`
      )

      setItems(result.data)
      setIsLoading(false)
    }

   fetchItems()
  }, [query])

  return (
    <div className='container'>
      <AmplifySignOut/>
      <SearchBar style={{ marginTop: "6%" }}  getQuery={(q) => setQuery(q)} />
      <CharacterGrid isLoading={isLoading} items={items} />
    </div>
  )
}

export default withAuthenticator(App)

The child component CharacterGrid looks like this:

import React from 'react'
import CharacterItem from './CharacterItem'

const CharacterGrid = ({items, isLoading}) => {

  return 
    isLoading 
      ? (<h1>Loading ...</h1>) 
      : (
        <section className='cards'>
          <p>{items.data}</p> //this does not work
          <p>{items.children}</p> //this does not work either
        </section>
      )
}

export default CharacterGrid 

All I want to do is show the names of the subreddits that are returned from the API for the query string the user enters. Where am I going wrong? I have also tried converting to JSON, and mapping through the responses using.map() but I keep getting errors no matter what I try. Where am I going wrong?

However, while I can console.log the data I need from the API I cannot seem to figure out how to display it.

Because Reddit API returns an array of subreddits you should use map() function to iterate over the array and convert each item into React element .

items.map(i => (
  <li key={i.data.display_name_prefixed}>
    {i.data.display_name}
  </li>
))

All I want to do is show the names of the subreddits that are returned from the API for the query string the user enters.

You need to inspect the data schema yourself and scrape the response properly.


Here is working example:

 const { useState, useEffect } = React; const App = () => { const [items, setItems] = useState([]); const [isLoading, setIsLoading] = useState(true); const [query, setQuery] = useState(""); useEffect(() => { setIsLoading(true); if (query.length >= 3) { axios(`https://www.reddit.com/subreddits/search.json?q=${query}`).then(response => setItems(response.data.data.children)).catch(error => console.log("Error", error)); } setIsLoading(false); }, [query]); return ( <div> <input type="text" value={query} onChange={e => setQuery(e.target.value)} /> <CharacterGrid items={items} isLoading={isLoading} /> </div> ); } const CharacterGrid = ({ items, isLoading }) => { return isLoading? ( <h1>Loading...</h1> ): ( <ul> {items.map(i => ( <li key={i.data.display_name_prefixed}> {i.data.display_name} ({i.data.display_name_prefixed}) </li> ))} </ul> ); }; ReactDOM.render(<App />, document.getElementById('root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script> <div id="root"></div>

In order to loop through the elements and eg: print the title, you could do the following.

items.data.children.map(child => <p> child.data.title </p>)

According to the response provided by reddit, reddit response

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM