11

This is my js file, which contains my images.

import React, { Component } from 'react';
import './Stopka.css';

class Stopka extends Component {
    render() {
        return (
            <div className="container">
                <footer className="row">
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        <h4>Some text</h4>
                    </div>
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        <img src={require("./icons/name1.png")} alt="" className="img-responsive" />
                        <img src={require("./icons/name2.png")} alt="" className="img-responsive" />
                        <img src={require("./icons/name3.png")} alt="" className="img-responsive" />
                        <img src={require("./icons/name4.png")} alt="" className="img-responsive" />
                    </div>
                </footer>
            </div>
        );
    }
}
export default Stopka;

And file which render this.

import React from 'react';
import ReactDOM from 'react-dom';
import Stopka from './Stopka';
import registerServiceWorker from './registerServiceWorker';



ReactDOM.render(<Stopka />, document.getElementById('stopka'));
registerServiceWorker();

For now my images is not rendering in much optimize mode, cuz if i want to add 20 or even more it'll be so much pain. I want to render it with loop or map function. Tried some but it doesn't work. Can you explain how can I do it?

This is what i tried.

import React, { Component } from 'react';
import './Stopka.css';

class Stopka extends Component {
    render() {
        let names = ['name1', 'name2', 'name3'];
        for (let i = 0; i < this.props.level; i++) {
            names.push(<image src={require("./icons/"+names+".png")} alt="" className="img-responsive" key={i} />  );
        }
        return (
            <div className="container">
                <footer className="row">
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        <h4>Some text</h4>
                    </div>
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        {names}
                    </div>
                </footer>
            </div>
        );
    }
}


export default Stopka;

Another try

import React, { Component } from 'react';
import './Stopka.css';

class Stopka extends Component {
    render() {
        let names = ['wood', 'sun'];

        let images = names.map(name => {

            <img
            src = {require("./icons/{name}.png")}
            alt = ""
                className="img-responsive" />
        });
        return (
            <div className="container">
                <footer className="row">
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        <h4>some text</h4>
                    </div>
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        { images }

                    </div>
                </footer>
            </div>
        );
    }
}


export default Stopka;

But this get error "Module not found: Can't resolve './icons/{name}.png' "

Brunhilda
  • 233
  • 1
  • 4
  • 19

2 Answers2

19

You can use the js map function combined with ES 6 template literals.

class Stopka extends Component {
    render() {

        const array = ["wood", "lake", "sun", "moon", "sea"];

        const images = array.map(image => {
           return <img key={image} src={require(`./icons/${image}.png`)} className="img-responsive" />
        });

        return (
            <div className="container">
                <footer className="row">
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        <h4>Some text</h4>
                    </div>
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                       { images }
                    </div>
                </footer>
            </div>
        );
    }
}
export default Stopka;
Paul Fitzgerald
  • 11,770
  • 4
  • 42
  • 54
  • Unexpected token, expected ; on line 8 near => Btw. from what I see, it render all images from folder icons? – Brunhilda Aug 16 '17 at 12:39
  • The names "name1, name2,... name100" was just for example. How can i do it with diffrent names? Like wood, lake, sun, moon, sea? Create array and put it in src like you did but without "name" before ${image} ? – Brunhilda Aug 16 '17 at 12:47
  • @Brunhilda no worres! – Paul Fitzgerald Aug 16 '17 at 14:19
  • Is there a way to populate an array dynamically so it has all the filenames from a specific folder including file extension? – Dobrobobr Jun 05 '19 at 14:01
  • @Dobrobobr perhaps this could work - https://stackoverflow.com/questions/47801606/list-folder-contents-with-reactjs – Paul Fitzgerald Jun 05 '19 at 14:39
  • 1
    @pau1fitzgerald Managed to do it by combining bits of code from different answers `function importAll(r) { return r.keys().map(r); } const images = importAll(require.context('static/UniLogo/', false, /\.(png|jpe?g|svg)$/)); const imageArray = images.map(function(image) { return ; }); ` – Dobrobobr Jun 05 '19 at 14:54
3

For others who had the same problem as me. This is working example as well. In my opinion with key index is better, cuz it not produce errors in console. Great for bigger projects.

import React, { Component } from 'react';
import './Stopka.css';

class Stopka extends Component {
    render() {
        let names = ['wood', 'sun', 'moon', 'sea'].map( (name, index) => {
            return <img key={index} className="img-responsive" alt="" src={require(`./icons/${name}.png`)} />
        } );
        return (
            <div className="container">
                <footer className="row">
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        <h4>some text</h4>
                    </div>
                    <div className="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                        { names }

                    </div>
                </footer>
            </div>
        );
    }
}


export default Stopka;

Thanks to Paul Fitzgerald for the guide.

Brunhilda
  • 233
  • 1
  • 4
  • 19
  • @brunhila I updated my answer to also include a key. I used the image though, you should check out this article as to why not to use the `index` as the key https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 – Paul Fitzgerald Aug 18 '17 at 12:07
  • Awesome. Thank you very much. – Brunhilda Aug 22 '17 at 07:38