1

This is the structure of the json being fetched. I am trying to render some of the nested threads data to a web page with react.

enter image description here

import react, {useState, useEffect} from "react";
import axios from 'axios'
import ReactJson from 'react-json-view'

const FeaturedBoards = () => {
    const [boards, setBoards] = useState([{page: '', threads: {}}]); 

useEffect(() => {
    fetchBoards();
}, []);

const fetchBoards = () => {
    axios.get('https://a.4cdn.org/po/catalog.json')
    .then((res) => {
        console.log(res.data);
        setBoards(res.data);
    })
    .catch((err) => {
        console.log(err);
    });
};
    if(boards === 0) {
        return <div>Loading...</div>;
    }
    else{
    return (
        <div>
            <h1>Featured Boards</h1>
            <div className='item-container'>
                {boards.map((board) => (
                    <div className='board' key={board.id}>
                        <p>{board['threads']}</p>
                    </div>
                ))}
            </div>
        </div>
    );
    }
};

export default FeaturedBoards;

I have tried everything to display some of the nested threads data but nothing comes up. I've tried doing a second call to map on board but no luck, storing it in a variable and calling from that still nothing. Am I doing something totally wrong?

enter image description here

6
  • Since the threads properties in your API data appear to be arrays, why are you initialising it as an object with useState([{page: '', threads: {}}])? That's what is causing the error. Also, why initialise with a single-element array in the first place? Why not just useState([])? Commented Oct 25, 2021 at 2:44
  • my thinking was you had to provide a template structure to be filled in. When I switch useState to that it gives me this error. Error: Objects are not valid as a React child (found: object with keys {no, sticky, closed, now, name, sub, com, filename, ext, w, h, tn_w, tn_h, tim, time, md5, fsize, resto, capcode, semantic_url, replies, images, omitted_posts, omitted_images, last_replies, last_modified}). If you meant to render a collection of children, use an array instead. Commented Oct 25, 2021 at 2:48
  • To this what you said to try useState([]) hard to repost the whole code down here lol Commented Oct 25, 2021 at 2:53
  • const [boards, setBoards] = useState([]); Commented Oct 25, 2021 at 2:54
  • Each board threads is an array of objects (presumably with properties like no, sticky, closed, etc). <p>{board['threads']}</p> just doesn't make sense for that data structure. As the error message says, "Objects (like the ones in board.threads) are not valid as a React child" Commented Oct 25, 2021 at 2:54

1 Answer 1

1

I believe this is more fully answered by How can I access and process nested objects, arrays or JSON?. but to explain for this particular data structure, keep reading.


Look at your actual data... boards is an array. Each element in it is an object with page (int) and threads (array) properties. Each threads array element is an object with other properties. You can use map to iterate arrays and return a JSX representation of the objects within.

For example

const [boards, setBoards] = useState([]); // start with an empty array
const [loading, setLoading] = useState(true)

useEffect(() => {
  fetchBoards().then(() => setLoading(false))
}, []);

const fetchBoards = async () => {
  const { data } = await axios.get('https://a.4cdn.org/po/catalog.json')
  setBoards(data)
}

return loading ? <div>Loading...</div> : (
  <div>
    <h1>Featured Boards</h1>
    <div className="item-container">
      {boards.map(board => (
        <div className="board" key={board.page}> <!-- 👈 note "page", not "id" -->
          {board.threads.map(thread => (
            <p>{thread.name}</p>
            <p>{thread.sub}</p>
            <p>{thread.com}</p>
            <!-- etc -->
          ))}
        </div>
      ))}
    </div>
  </div>
)
Sign up to request clarification or add additional context in comments.

3 Comments

Worked! thank you that was what I was trying to do, does changing the key={} from id to page do anything?
See reactjs.org/docs/lists-and-keys.html#keys. Your board objects don't appear to have id properties so you'd be setting each key to undefined which would produce "Warning: Each child in a list should have a unique "key" prop."
ahhh makes sense from errors I had been seeing, I'll check that out thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.