简体   繁体   中英

Render JSON data (from reddit API) with reactjs

Very new to React, so I might be approaching this the wrong way... I want my app to take input from a text input field, retrieve a JSON from the reddit API (the url is built from the text input), and then render data from the JSON, looping through each of the entries. I'm using useState to trigger the data render. I can successfully retrieve the data and output specific values, but I want to be able to have a loop that dynamically outputs the data into various HTML elements.

Here's what I have so far that allows me to output some specific values as an example:

import React, { useState } from 'react';

const App = () => {
  const [retrievedData, setRetrievedData] = useState([])
  
  const runSearch = async() => {
    const searchInput = document.getElementById('searchInput').value
    const searchUrl = 'https://www.reddit.com/r/' + searchInput + '/new/.json?limit=5'
    const response = await fetch(searchUrl)
    const redditResponse = await response.json()

    setRetrievedData(<>
    <p>{JSON.stringify(redditResponse.data.children[0].data.author)}</p>
    <p>{JSON.stringify(redditResponse.data.children[0].data.title)}</p>
    </>)
  }

  return (
    <>
      <section>
        <input type="text" id='searchInput' placeholder='Enter a subreddit...'></input>
        <button onClick={runSearch}>
          Get Data
        </button>
        <div>{retrievedData}</div>
      </section>
    </>
  );
};

export default App;

And here's an example of the JSON that is retrieved from the reddit API, just stripped down with only the example values I use in my code above:

{
  "kind": "Listing",
  "data": {
    "modhash": "",
    "dist": 5,
    "children": [
      {
        "kind": "t3",
        "data": {
          "author": "author1",
          "title": "title1"
        }
      },
      {
        "kind": "t3",
        "data": {
          "author": "author2",
          "title": "title2"
        }
      },
      {
        "kind": "t3",
        "data": {
          "author": "author3",
          "title": "title3"
        }
      },
      {
        "kind": "t3",
        "data": {
          "author": "author4",
          "title": "title4"
        }
      },
      {
        "kind": "t3",
        "data": {
          "author": "author5",
          "title": "title5"
        }
      }
    ],
    "after": "t3_jnu0ik",
    "before": null
  }
}

I just need the final rendered output to be something like:

<h2>TITLE 1</h2>
<h4>AUTHOR 1</h4>
<p>SELFTEXT 1</p>

...and repeated for each post data that is retrieved.

I've seen a variety of different ways to render JSON data and many of them show either loops and/or the .map() method, but I can't ever seem to get those to work, and wonder if it's an issue with the useState. Perhaps there is some way I should be rendering the data some other way?

You don't need set jsx to state, you can directly iterate children data with map

Try this

const App = () => {
  const [retrievedData, setRetrievedData] = useState([])
  
  const runSearch = async() => {
    const searchInput = document.getElementById('searchInput').value
    const searchUrl = 'https://www.reddit.com/r/' + searchInput + '/new/.json?limit=5'
    const response = await fetch(searchUrl)
    const redditResponse = await response.json()
    if (redditResponse.data.children && redditResponse.data.children.length) {
      setRetrievedData(redditResponse.data.children)
    }
  }

  return (
    <>
      <section>
        <input type="text" id='searchInput' placeholder='Enter a subreddit...'></input>
        <button onClick={runSearch}>
          Get Data
        </button>
        <div>
          {
            retrievedData.map((children, index) => {
              return (
                <div key={children.data.author + index}>
                  <div>Kind: { children.kind }</div>
                  <div>Author: { children.data.author }</div>
                  <div>Title: { children.data.title }</div>
                </div>
              )
            })
          }
        </div>
      </section>
    </>
  );
};

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