DEV Community

Nicholas Wilson
Nicholas Wilson

Posted on

Help with React .map through JSON data.

I just signed up here to get some help as i'm new to react and this is where reactjs.org suggested i go for help, and i'm not sure if this is the right place to ask questions about code but I have an issue that I can't seem to figure out.

I have a .json file in one of my directories and i've imported it into one of my .js files.

I'm trying to set the state to the .json file which i've done successfully. However, I can't figure out how to map through the data and display it in my render method properly.

//other react imports
import data from '../data/portfolio.json';

class Portfolio extends React.Component {
    constructor(props) {
        super(props);
        this.state = {data}
    }

    render() {     
        return(
            <div>
                <a href={this.state.data.portfolio[0].url}>
                   <img className="img-fluid" 
                        src={this.state.data.portfolio[0].image} 
                        alt={this.state.data.portfolio[0].site} />
                   <p>{this.state.data.portfolio[0].site}</p>
                </a>
            </div>
        )
    }
}

This works fine, but I want to avoid having to create multiple anchor, image and paragraph tags and loop through to display everything. Any suggestions or places I can go to read how to do this with a local .json file? I tried this...

const myData = this.state.data;
const listItems = myData.map((myData) =>
  <li>{myData}</li>
);

This doesn't work though because I think .map is used for arrays online. Should I use a for loop or something else?

Top comments (2)

Collapse
 
higormarques profile image
Higor Neves Marques • Edited

First, since your data will not change, you don’t need put it into a state.

Try:

import data from '../data/portfolio.json';
...
const listItems = data.map(item =>
  <div>
        <a href={item.url}>
            <img className="img-fluid" 
                  src={item.image} 
                  alt={item.site} />
             <p>{item.site}</p>
          </a>
     </div>
);
...
render() {
    return(
        <div>
            { listItems }
        </div>
      )
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
utkal97 profile image
Utkal • Edited

The solution given by Higor Neves is perfect. Here is another way to solve : You can create a functional component RenderPortfolio that renders each portfolio element in your data.json list. While mapping through each element don't forget to give a key for each div being created. For now I have given 'url' property hoping that it will be unique. I hope there wil be no syntactical or logical errors.

//other react imports
import data from '../data/portfolio.json';

function RenderPortfolio({portfolio}) {
    return (
        <a href={portfolio.url}>
            <img className="img-fluid" 
                src={portfolio.image} 
                alt={portfolio.site} />
            <p>{portfolio.site}</p>
        </a>
    );
}

class Portfolio extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data : data
        };
    }

    render() {

        const portfolio_list = this.state.data.map( (element) => {
            return (
                <div key={element.url}>
                    <RenderPortfolio portfolio = {element} />
                </div>
            );
        });

        return(
            <React.Fragment>
                {portfolio_list}
            </React.Fragment>
        );
    }
}