Native reagieren - Image Require-Modul mit dynamischen Namen


84

Ich erstelle gerade eine Test-App mit React Native. Das Image-Modul hat bisher einwandfrei funktioniert.

Wenn ich beispielsweise ein Bild mit dem Namen hatte avatar, funktioniert das folgende Codefragment einwandfrei.

<Image source={require('image!avatar')} />

Aber wenn ich es in eine dynamische Zeichenfolge ändere, bekomme ich

<Image source={require('image!' + 'avatar')} />

Ich bekomme den Fehler:

Unbekanntes Modul "image! Avatar" erforderlich. Wenn Sie sicher sind, dass das Modul vorhanden ist, starten Sie den Packager neu.

Natürlich ist dies ein erfundenes Beispiel, aber dynamische Bildnamen sind wichtig. Unterstützt React Native keine dynamischen Bildnamen?

Reagieren Sie auf einen nativen Fehler mit einem dynamischen Bildnamen


1
Ich habe ein ähnliches Problem mit Vue festgestellt. Die
Alonad

Antworten:


70

Dies wird in der Dokumentation im Abschnitt " Statische Ressourcen " behandelt:

Die einzige Möglichkeit, auf ein Bild im Bundle zu verweisen, besteht darin, require ('image! Name des Assets') buchstäblich in die Quelle zu schreiben.

// GOOD
<Image source={require('image!my-icon')} />

// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('image!' + icon)} />

// GOOD
var icon = this.props.active ? require('image!my-icon-active') : require('image!my-icon-inactive');
<Image source={icon} />

Sie müssen jedoch auch daran denken, Ihre Bilder zu einem xcassets-Bundle in Ihrer App in Xcode hinzuzufügen, obwohl es aus Ihrem Kommentar hervorgeht, dass Sie dies bereits getan haben.

http://facebook.github.io/react-native/docs/image.html#adding-static-resources-to-your-app-using-images-xcassets


1
Wo soll ich Bilder hinzufügen, ich benutze React Native für Android, im Zeichenordner?
coderzzz18

2
Der obige Link ist falsch, der Artikel ist jetzt bei facebook.github.io/react-native/docs/images.html
app_sciences

45
Hallo, wie geht das, wenn ich Hunderte von Bildern benötige?
Chanjianyi

1
@chanjianyi Ich bin in der gleichen Situation :-(
Mo.

1
"Require" funktioniert auf iOS-Geräten für mich nicht. Irgendeine Idee warum?
Arthur Medeiros

57

Das hat bei mir funktioniert:

Ich habe eine benutzerdefinierte Bildkomponente erstellt, die einen Booleschen Wert verwendet, um zu überprüfen, ob das Bild aus dem Web stammt oder aus einem lokalen Ordner übergeben wird.

// In index.ios.js after importing the component
<CustomImage fromWeb={false} imageName={require('./images/logo.png')}/>

// In CustomImage.js which is my image component
<Image style={styles.image} source={this.props.imageName} />

Wenn Sie den Code sehen, anstatt einen der folgenden zu verwenden:

// NOTE: Neither of these will work
source={require('../images/'+imageName)} 
var imageName = require('../images/'+imageName)

Ich schicke das Ganze nur require('./images/logo.png')als Requisite. Es klappt!


5
Diese Antwort verdient mehr Anerkennung. Es funktioniert absolut, wenn Sie die require-Anweisung deklarieren und als Requisite übergeben. Vielen Dank für Ihre einfache Erklärung, ich wünschte nur, andere wären so klar.
Dazziola

1
Die Requisiten wirken Wunder. Das sollte in den offiziellen Dokumenten angegeben werden.
Dasmikko

1
class CustomImage extends Component { constructor(props) { super(props); } render() { return ( <Image source={this.props.imageName} resizeMode="contain" style={{ height: 24, width: 24 }} /> ); } } <CustomImage fromWeb={false} imageName={require(`../../images/phone-${item.status}.png`)} />
Pablo

1
In der übergeordneten Komponente habe ich <CustomImage fromWeb={false} imageName={require(../../assets/icons/${el.img}.png )} /> und dies in der untergeordneten Komponenteclass CustomImage extends Component { constructor(props) { super(props); } render() { return ( <Image source={this.props.imageName} resizeMode="contain" style={{ height: 24, width: 24 }} /> ); } }
Walter Monecke

2
Genie pur, genau das habe ich gesucht :)
Sumit Sahoo

51

RELEVANT, WENN SIE BEKANNTE BILDER (URLS) HABEN:

So habe ich mich durch dieses Problem gehackt:

Ich habe eine Datei mit einem Objekt erstellt, in dem das Bild und der Name des Bildes gespeichert sind:

const images = {
  dog: {
    imgName: 'Dog', 
    uri: require('path/to/local/image')
  },
  cat: {
    imgName: 'Cat on a Boat', 
    uri: require('path/to/local/image')
  }
}

export { images };

Dann habe ich das Objekt in die Komponente importiert, in der ich es verwenden möchte, und meine bedingte Darstellung wie folgt durchgeführt:

import { images } from 'relative/path';

if (cond === 'cat') {
  let imgSource = images.cat.uri;
}

<Image source={imgSource} />

Ich weiß, dass dies nicht der effizienteste Weg ist, aber es ist definitiv eine Problemumgehung.

Ich hoffe es hilft!


3
Ordentliche Lösung für bekannte Bilder
Tedy Kanjirathinkal

1
@TedyKanjirathinkal Ich bin froh, dass es geholfen hat!
Walter Monecke

1
Vielen Dank, dies wird nützlich sein
Truca

@ WalterMonecke: Ich bekomme einen ganzzahligen Wert, wenn uns das gefällt
Sabir

24

Wenn Sie nach einer Möglichkeit suchen, eine Liste zu erstellen, indem Sie beispielsweise ein JSON-Array Ihrer Bilder und Beschreibungen durchlaufen, funktioniert dies für Sie.

  1. Erstellen Sie eine Datei (für unsere JSON-Datenbank), z. B. ProfilesDB.js:

const Profiles=[
	  {
	  "id" : "1",
	  "name" : "Peter Parker",
	  "src" : require('../images/user1.png'),
	  "age":"70",
	},
	{
	"id" : "2",
	"name" : "Barack Obama",
	"src" : require('../images/user2.png'),
	"age":"19",
	},
	{
	"id" : "3",
	"name" : "Hilary Clinton",
	"src" : require('../images/user3.png'),
	"age":"50",
	}
]
export default Profiles;

  1. Importieren Sie dann die Daten in unsere Komponente und durchlaufen Sie die Liste mit einer FlatList:

import Profiles from './ProfilesDB.js';

<FlatList
  data={Profiles}
  keyExtractor={(item, index) => item.id}
  renderItem={({item}) => (
    <View>
      <Image source={item.src} />
      <Text>{item.name}</Text>
    </View>
  )}
/>

Viel Glück!


3
Danke, das hat bei mir nach so viel Frust funktioniert!
Cherucole

11

Wie in der React Native-Dokumentation angegeben, müssen alle Ihre Bildquellen geladen werden, bevor Sie Ihr Bundle kompilieren können

Eine andere Möglichkeit, dynamische Bilder zu verwenden, ist die Verwendung einer switch-Anweisung. Angenommen, Sie möchten einen anderen Avatar für einen anderen Charakter anzeigen. Sie können Folgendes tun:

class App extends Component {
  state = { avatar: "" }

  get avatarImage() {
    switch (this.state.avatar) {
      case "spiderman":
        return require('./spiderman.png');
      case "batman":
        return require('./batman.png');
      case "hulk":
        return require('./hulk.png');
      default:
        return require('./no-image.png');
    }
  }

  render() {
    return <Image source={this.avatarImage} />
  }
}

Überprüfen Sie den Snack: https://snack.expo.io/@abranhe/dynamic-images

Denken Sie auch daran, wenn Ihr Bild online ist, haben Sie keine Probleme. Sie können Folgendes tun:

let superhero = "spiderman";

<Image source={{ uri: `https://some-website.online/${superhero}.png` }} />

7

Erstellen Sie zunächst eine Datei mit dem erforderlichen Bild. - Reagieren Sie auf diese Weise müssen native Bilder geladen werden.

Assets / Index.js

export const friendsandfoe = require('./friends-and-foe.png'); 
export const lifeanddeath = require('./life-and-death.png'); 
export const homeandgarden = require('./home-and-garden.png');

Importieren Sie nun alle Ihre Assets

App.js.

import * as All  from '../../assets';

Sie können Ihr Bild jetzt als interpolierten Wert verwenden, wobei imageValue (vom Backend eingehend) mit der benannten lokalen Datei identisch ist, dh: 'homeandgarden':

<Image style={styles.image} source={All[`${imageValue}`]}></Image>

Schöne Lösung, es hat mir sehr geholfen! Tks.
Fryla-Cristian Marucci

Keine Sorgen! Konnte hier keine gute Lösung finden, also habe ich mir eine eigene ausgedacht :) Ich bin froh, geholfen zu haben.
HannahCarney

5

Wichtiger Teil hier: Wir können den Bildnamen nicht in der Anforderung wie [erfordern ('item' + vairable + '. Png')] verknüpfen

Schritt 1: Wir erstellen eine ImageCollection.js-Datei mit der folgenden Sammlung von Bildeigenschaften

ImageCollection.js
================================
export default images={
    "1": require("./item1.png"),
    "2": require("./item2.png"),
    "3": require("./item3.png"),
    "4": require("./item4.png"),
    "5": require("./item5.png")
}

Schritt 2: Importieren Sie das Bild in Ihre App und bearbeiten Sie es nach Bedarf

class ListRepoApp extends Component {

    renderItem = ({item }) => (
        <View style={styles.item}>
            <Text>Item number :{item}</Text>
            <Image source={Images[item]}/>
        </View>
    );

    render () {
        const data = ["1","2","3","4","5"]
        return (
            <FlatList data={data} renderItem={this.renderItem}/>
        )
    }
}

export default ListRepoApp;

Wenn Sie eine ausführliche Erklärung wünschen, können Sie dem folgenden Link folgen. Besuchen Sie https://www.thelearninguy.com/react-native-require-image-using-dynamic-names

Mit freundlicher Genehmigung von https://www.thelearninguy.com


5
import React, { Component } from 'react';
import { Image } from 'react-native';

class Images extends Component {
  constructor(props) {
    super(props);
    this.state = {
           images: {
                './assets/RetailerLogo/1.jpg': require('../../../assets/RetailerLogo/1.jpg'),
                './assets/RetailerLogo/2.jpg': require('../../../assets/RetailerLogo/2.jpg'),
                './assets/RetailerLogo/3.jpg': require('../../../assets/RetailerLogo/3.jpg')
            }
    }
  }

  render() {
    const {  images } = this.state 
    return (
      <View>
        <Image
                            resizeMode="contain"
                            source={ images['assets/RetailerLogo/1.jpg'] }
                            style={styles.itemImg}
                        />
     </View>
  )}
}


2

Für ein dynamisches Bild mit

this.state={
       //defualt image
       newimage: require('../../../src/assets/group/kids_room3.png'),
       randomImages=[
         {
            image:require('../../../src/assets/group/kids_room1.png')
          },
         {
            image:require('../../../src/assets/group/kids_room2.png')
          }
        ,
         {
            image:require('../../../src/assets/group/kids_room3.png')
          }
        
        
        ]

}

wenn ich die Taste drücke- (ich wähle Bild Zufallszahl zwischen 0-2))

let setImage=>(){
//set new dynamic image 
this.setState({newimage:this.state.randomImages[Math.floor(Math.random() * 3)];
})
}

Aussicht

<Image
        style={{  width: 30, height: 30 ,zIndex: 500 }}
        
        source={this.state.newimage}
      />


1
 <StyledInput text="NAME" imgUri={require('../assets/userIcon.png')} ></StyledInput> 

<Image
            source={this.props.imgUri}
            style={{
              height: 30,
              width: 30,
              resizeMode: 'contain',
            }}
          />   

In meinem Fall habe ich so viel versucht, aber schließlich funktioniert es StyledInput Komponentenname Bild im StyledInput, wenn Sie immer noch nicht verstehen, lassen Sie es mich wissen


1

Sagen Sie, wenn Sie eine Anwendung haben, die ähnliche Funktionen wie meine hat. Wo Ihre App meistens offline ist und Sie die Bilder nacheinander rendern möchten. Im Folgenden finden Sie den Ansatz, der in React Native Version 0.60 für mich funktioniert hat.

  1. Erstellen Sie zunächst einen Ordner mit dem Namen Ressourcen / Bilder und platzieren Sie alle Ihre Bilder dort.
  2. Erstellen Sie nun eine Datei mit dem Namen Index.js (at Resources / Bilder) , die für die Indizierung alle die Bilder in den verantwortlich ist Reources / Bilder - Ordner.

const Images = {'image1': require ('./ 1.png'), 'image2': require ('./ 2.png'), 'image3': require ('./ 3.png')}

  1. Erstellen Sie nun eine Komponente mit dem Namen ImageView in einem Ordner Ihrer Wahl. Man kann funktionale, Klassen- oder konstante Komponenten erstellen. Ich habe die Const-Komponente verwendet. Diese Datei ist abhängig vom Index für die Rückgabe des Bildes verantwortlich.
import React from 'react';
import { Image, Dimensions } from 'react-native';
import Images from './Index';
const ImageView = ({ index }) => {
    return (
        <Image
            source={Images['image' + index]}
        />
    )
}
export default ImageView;
  1. Verwenden Sie nun von der Komponente aus, wo immer Sie die statischen Bilder dynamisch rendern möchten, einfach die ImageView-Komponente und übergeben Sie den Index.

    <ImageView index = {this.qno + 1} />


-2

Sie sollten dafür ein Objekt verwenden.

Angenommen, ich habe eine AJAX-Anforderung an eine API gesendet und sie gibt einen Bildlink zurück, den ich speichern werde, um Folgendes anzugeben imageLink:

source={{uri: this.state.imageLink}}


3
Für dynamische var img = "../img/icons/"+img_name+"_selected.png"; <br/> <Image source={{uri: img}} resizeMode={'contain'} />
Robert Tomas G IV

3
Ein Hack dafür, wenn Sie wissen, dass alle img_name-Varianten diesen Weg gehen würden:var images = { 'first': require('../first.png'), 'second': require('../second.png') } <Image source={{uri:images[img_name]}} resizeMode={'contain'} />
Gabriel Lupu

2
Bitte beachten Sie, dass für @GabrielLupus Vorschlag: Sie ordnen auf diese Weise alle Bilder im Speicher zu. Dies hängt von der Anzahl der Bilder und ihrer Größe ab. Es treten jedoch wahrscheinlich Speicherfehler auf.
Lashae
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.