首页 > 解决方案 > Dynamically importing an image source that has been passed as a prop in React

问题描述

I'm trying to dynamically import some images in one of my react components. The names of the images are stored in a JSON file which are then being passed to the component as a prop.

This is the parent component where the data is being passed in:

const GridBlocks = gridItems.map(({ imageSrc, alt, ...textProps }, index) => (
<div key={`grid-section-${index}`} styleName="grid-section">
    <ImageBlock imageSrc={imageSrc} alt={alt} />
    <TextBlock {...textProps} />
</div>

));

Now the problem I'm facing is that obviously I cant just import prop from 'bar' as usual since the child component won't have a clue what 'prop' is.

I've had a look around and I think the solution should look something like this? (except y'know....working). Particularly around 'require.context' but I just can't figure out the implementation.

import React from 'react';
import PropTypes from 'prop-types';
import './ImageBlock.css';

const assetRequire = require.context('Images/howItWorks/', true, /\.(png|jpg|svg)$/);

const ImageBlock = async ({ imageSrc, alt }) => {
    const imageSrc1x = assetRequire(`${imageSrc}.png`);
    const imageSrc2x = assetRequire(`${imageSrc}@2x.png`);

    return (
        <img
            src={imageSrc1x}
            srcSet={`${imageSrc1x} 1x, ${imageSrc2x} 2x`}
            alt={alt}
            styleName="image-block"
        />
    );
};

ImageBlock.propTypes = {
    imageSrc: PropTypes.string.isRequired,
    alt: PropTypes.string.isRequired,
};

export default ImageBlock;

Any help would be greatly appreciated.

标签: javascriptreactjs

解决方案


所以经过更多搜索后,我在这里找到了一个可行的解决方案

使用 webpack 从目录中动态导入图片

我稍微重构的版本如下

import React from 'react';
import PropTypes from 'prop-types';
import './ImageBlock.css';


function importAll(r) {
    const images = {};
    r.keys().map((item, index) => { images[item.replace('./', '')] = r(item); }); //eslint-disable-line
    return images;
}

const images = importAll(require.context('Images/howItWorks/', false, /\.(png|jpe?g|svg)$/));

const ImageBlock = ({ imageSrc, alt }) => {
    const imageSrc1x = images[`${imageSrc}.png`];
    const imageSrc2x = images[`${imageSrc}@2x.png`];

    return (
        <img
            src={imageSrc1x}
            srcSet={`${imageSrc1x} 1x, ${imageSrc2x} 2x`}
            alt={alt}
            styleName="image-block"
        />
    );
};

ImageBlock.propTypes = {
    imageSrc: PropTypes.string.isRequired,
    alt: PropTypes.string.isRequired,
};

export default ImageBlock;


推荐阅读