Динамічне додавання зображень React Webpack


77

Я намагався зрозуміти, як динамічно додавати зображення за допомогою React та Webpack. У мене є папка із зображеннями під src / images та компонент під src / components / index . Я використовую url-loader з наступною конфігурацією для webpack

    {
      test: /\.(png|jpg|)$/,
      loader: 'url-loader?limit=200000'
    }

У межах компонента, який я знаю, я можу додати require (image_path) для певного зображення у верхній частині файлу перед тим, як створити компонент, але я хочу зробити компонент загальним і надати йому властивість із шляхом до зображення, яке передається з батьківський компонент.

Я спробував:

<img src={require(this.props.img)} />

Що стосується фактичної властивості, я перепробував майже кожен шлях, який я можу придумати, до зображення з кореня проекту, з кореня додатка для реагування та з самого компонента.

Файлова система

|-- src
|   ` app.js
|   `--images
|      ` image.jpg
|      ` image.jpg
|   `-- components
|      `parent_component.js
|      `child_component.js

Батьківський компонент - це, в основному, просто контейнер, в якому вміщуються кілька дочірніх елементів, тому ...

<ChildComponent img=data.img1 />
<ChildComponent img=data.img2 />
etc....

Чи є спосіб зробити це, використовуючи реакцію та веб-пакет за допомогою завантажувача url, або я просто йду невірним шляхом, щоб підійти до цього?

Відповіді:


98

За допомогою url-loader, описаного тут ( SurviveJS - Завантаження зображень ), ви можете потім використовувати у своєму коді:

import LogoImg from 'YOUR_PATH/logo.png';

і

<img src={LogoImg}/>

Редагувати: точність, зображення вставляються в архів js за допомогою цієї техніки. Це може бути гідно для невеликих зображень, але використовуйте техніку з розумом.


1
Я хотів би знати, як завантажити це зображення та API, який повертає зображення.
Оракул

3
Я не впевнений, що розумію: якщо ви хочете, щоб браузер користувача завантажував зображення з API, це не має нічого спільного з webpack. Просто використовуйте змінну (можливо, визначену після виклику API) як <img> src. Ідея тут полягала в тому, щоб включити зображення до своїх джерел та архіву веб-пакета. (Див stackoverflow.com/questions/32612912 / ... )
mlorber

1
Дякую, це чудово працює. У статті, яку ви цитували, також згадується в кінці, якщо ви використовуєте React, тоді ви використовуєте babel-plugin-transform-response-jsx-img-import для автоматичного створення імпорту. Таким чином , ви можете просто написати <IMG SRC = "YOUR_PATH / logo.png" />
Гемам Бахрані

Попередження: url-loader вбудує файл зображення у базовий рядок ascii base64. Це зменшує кількість звернень до файлів, необхідних для завантаження сторінки, але ціною більшої кількості байт для завантаження. Тож, можливо, краще використовувати файл-завантажувач для виробництва.
hrabinowitz

Так, зображення вбудовані за допомогою цієї техніки. Це повністю залежить від ваги файлу. Для маленьких (значки в основному для мене) це може бути гідно. Я відредагую відповідь
mlorber

23

Якщо ви поєднуєте свій код на стороні сервера, то ніщо не заважає вам вимагати активів безпосередньо з jsx:

<div>
  <h1>Image</h1>
  <img src={require('./assets/image.png')} />
</div>

3
Це те, що мені потрібно було використовувати в моїй ситуації, коли я не знаю файл зображення, поки компонент не буде побудований. Я передаю imageFilenameопору, а потім використовую <img src={require(`./images/${imageFilename}`)} />. Дякуємо за розміщення.
Brendan Moore

1
@BrendanMoore, але пам’ятайте, що у вашому випадку пакет (скажімо веб-пакет) додасть всі зображення з imagesпапки до останнього пакета.
James Akwuh,

1
Саме те, що я шукав. Дякую @JamesAkwuh
Самрат Саха

5
Якщо це не працює, додайте .default після require (). Наприклад: я використовую like const src = require(assets / images / $ {name}).default;
master_dodo

12

ОНОВЛЕННЯ : це лише тестоване з рендерингом на стороні сервера (універсальний Javascript) ось мій шаблон .

Тільки завантажувач файлів дозволяє завантажувати зображення динамічно - фокус полягає у використанні рядків шаблонів ES6, щоб Webpack міг їх взяти:

Це НЕ буде працювати. :

const myImg = './cute.jpg'
<img src={require(myImg)} />

Щоб це виправити, просто використовуйте натомість рядки шаблонів:

const myImg = './cute.jpg'
<img src={require(`${myImg}`)} />

webpack.config.js:

var HtmlWebpackPlugin =  require('html-webpack-plugin')
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')

module.exports = {
  entry : './src/app.js',
  output : {
    path : './dist',
    filename : 'app.bundle.js'
  },
  plugins : [
  new ExtractTextWebpackPlugin('app.bundle.css')],
  module : {
    rules : [{
      test : /\.css$/,
      use : ExtractTextWebpackPlugin.extract({
        fallback : 'style-loader',
        use: 'css-loader'
      })
    },{
      test: /\.js$/,
      exclude: /(node_modules)/,
      loader: 'babel-loader',
      query: {
        presets: ['react','es2015']
      }
    },{
      test : /\.jpg$/,
      exclude: /(node_modules)/,
      loader : 'file-loader'
    }]
  }
}

2
Відсутній фрагмент для мене був тестом у конфігурації webpack. Дякую.
Дін Пулен,

8

Якщо ви шукаєте спосіб імпортувати всі зображення із зображення

// Import all images in image folder
function importAll(r) {
    let images = {};
    r.keys().map((item, index) => { images[item.replace('./', '')] = r(item); });
    return images;
}

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

Тоді:

<img src={images['image-01.jpg']}/>

Ви можете знайти оригінальний потік тут: Динамічно імпортуйте зображення з каталогу за допомогою webpack


6

Отже, вам потрібно додати оператор імпорту для вашого батьківського компонента:

class ParentClass extends Component {
  render() {
    const img = require('../images/img.png');
    return (
      <div>
        <ChildClass
          img={img}
        />
      </div>
    );
  }
}

а в класі дитини:

class ChildClass extends Component {
  render() {
    return (
      <div>
          <img
            src={this.props.img}
          />
      </div>
    );
  }
}

3

Ви не вставляєте зображення в пакет. Вони викликаються через браузер. Тож його;

var imgSrc = './image/image1.jpg';

return <img src={imgSrc} />

3
але що, якщо ви не знаєте зображення під час збірки? Що робити, якщо URL-адреса зображення складається під час виконання?
JBCP

Мета завантажувача, який ви використовуєте, насправді НЕ використовувати URL-адресу у своєму коді, а потенційно мати можливість вбудувати зображення в архів, якщо воно досить мало (кращі можливості)
mlorber,

2

ось код

    import React, { Component } from 'react';
    import logo from './logo.svg';
    import './image.css';
    import Dropdown from 'react-dropdown';
    import axios from 'axios';

    let obj = {};

    class App extends Component {
      constructor(){
        super();
        this.state = {
          selectedFiles: []
        }
        this.fileUploadHandler = this.fileUploadHandler.bind(this);
      }

      fileUploadHandler(file){
        let selectedFiles_ = this.state.selectedFiles;
        selectedFiles_.push(file);
        this.setState({selectedFiles: selectedFiles_});
      }

      render() {
        let Images = this.state.selectedFiles.map(image => {
          <div className = "image_parent">

              <img src={require(image.src)}
              />
          </div>
        });

        return (
            <div className="image-upload images_main">

            <input type="file" onClick={this.fileUploadHandler}/>
            {Images}

            </div>
        );
      }
    }

    export default App;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.