React Native - Modulo di richiesta immagine utilizzando nomi dinamici


87

Attualmente sto creando un'app di test utilizzando React Native. Il modulo Immagine, finora, ha funzionato bene.

Ad esempio, se avessi un'immagine denominata avatar, lo snippet di codice seguente funziona bene.

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

Ma se lo cambio in una stringa dinamica, ottengo

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

Ottengo l'errore:

Richiede il modulo sconosciuto "immagine! Avatar". Se sei sicuro che il modulo sia presente, prova a riavviare il packager.

Ovviamente questo è un esempio artificioso, ma i nomi delle immagini dinamiche sono importanti. React Native non supporta i nomi delle immagini dinamiche?

Reagisce all'errore nativo con il nome dell'immagine dinamica


1
Ho incontrato problema simile con Vue, risposta è qui stackoverflow.com/questions/40491506/...
Alonad

Risposte:


73

Questo è trattato nella documentazione nella sezione " Risorse statiche ":

L'unico modo consentito per fare riferimento a un'immagine nel bundle è scrivere letteralmente require ('image! Name-of-the-asset') nel sorgente.

// 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} />

Tuttavia, devi anche ricordarti di aggiungere le tue immagini a un pacchetto xcassets nella tua app in Xcode, anche se dal tuo commento sembra che tu l'abbia già fatto.

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


1
dove devo aggiungere immagini, sto usando React Native per Android, nella cartella disegnabile?
coderzzz18

2
Il collegamento sopra non è corretto, l'articolo è ora su facebook.github.io/react-native/docs/images.html
app_sciences

51
ciao, come fare se ho bisogno di centinaia di immagini?
chanjianyi

1
@chanjianyi Sono nella stessa situazione :-(
Lu.

1
"Richiedi" non funziona sui dispositivi IOS per me. Qualsiasi ideia perché?
Arthur Medeiros

59

Questo ha funzionato per me:

Ho creato un componente immagine personalizzato che accetta un valore booleano per verificare se l'immagine proviene dal Web o viene trasferita da una cartella locale.

// 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} />

Se vedi il codice, invece di usare uno di questi:

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

Sto solo inviando l'intero require('./images/logo.png')come sostegno. Funziona!


5
Questa risposta merita più credito. Funziona assolutamente quando dichiari l'istruzione require e passi come prop. Grazie mille per la tua semplice spiegazione, vorrei solo che gli altri fossero altrettanto chiari.
dazziola

1
L'oggetto di scena fa miracoli. Questo dovrebbe essere dichiarato sui documenti ufficiali.
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
Nel componente genitore ho <CustomImage fromWeb={false} imageName={require(../../assets/icons/${el.img}.png )} /> e questo nel componente figlioclass CustomImage extends Component { constructor(props) { super(props); } render() { return ( <Image source={this.props.imageName} resizeMode="contain" style={{ height: 24, width: 24 }} /> ); } }
Walter Monecke

2
Puro genio, questo è esattamente quello che stavo cercando :)
Sumit Sahoo

54

RILEVANTE SE AVETE IMMAGINI CONOSCIUTE (URL):

Il modo in cui ho risolto questo problema:

Ho creato un file con un oggetto che memorizzava l'immagine e il nome dell'immagine:

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 };

Quindi ho importato l'oggetto nel componente in cui voglio usarlo ed eseguo semplicemente il rendering condizionale in questo modo:

import { images } from 'relative/path';

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

<Image source={imgSource} />

So che non è il modo più efficiente ma è sicuramente una soluzione alternativa.

Spero che sia d'aiuto!


3
Ottima soluzione per gestire una serie nota di immagini
Tedy Kanjirathinkal

1
@TedyKanjirathinkal Sono contento che abbia aiutato!
Walter Monecke

1
Grazie, sarà utile
Truca

@WalterMonecke: sto ottenendo un valore intero se facciamo così
sabir

30

Se stai cercando un modo per creare un elenco eseguendo un ciclo attraverso un array JSON delle tue immagini e descrizioni, ad esempio, questo funzionerà per te.

  1. Crea un file (per contenere il nostro database JSON) ad esempio 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. Quindi importa i dati nel nostro componente e scorri l'elenco utilizzando una 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>
  )}
/>

In bocca al lupo!


3
Grazie, ha funzionato per me dopo così tanta frustrazione!
cherucole

12

Come dice la documentazione nativa di React , tutte le sorgenti delle immagini devono essere caricate prima di compilare il pacchetto

Quindi un altro modo in cui puoi usare immagini dinamiche è usare un'istruzione switch. Supponiamo che tu voglia visualizzare un avatar diverso per un personaggio diverso, puoi fare qualcosa del genere:

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} />
  }
}

Controlla lo spuntino: https://snack.expo.io/@abranhe/dynamic-images

Inoltre, ricorda se la tua immagine è online non hai problemi, puoi fare:

let superhero = "spiderman";

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

8

Innanzitutto, crea un file con l'immagine richiesta: le immagini native di React devono essere caricate in questo modo.

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');

Ora importa tutti i tuoi asset

App.js

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

Ora puoi usare la tua immagine come valore interpolato dove imageValue (proveniente dal backend) è lo stesso del file locale denominato, ad esempio: 'homeandgarden':

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

Bella soluzione, mi ha aiutato molto! Tks.
Fryla- Cristian Marucci

Nessun problema! Non sono riuscito a trovare una buona soluzione qui, quindi ne ho creata una mia :) Sono contento di aver aiutato.
HannahCarney

6

Parte importante qui: non possiamo concatenare il nome dell'immagine all'interno del require come [require ('item' + vairable + '. Png')]

Passaggio 1: creiamo un file ImageCollection.js con la seguente raccolta di proprietà dell'immagine

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")
}

Passaggio 2: importa l'immagine nella tua app e manipola se necessario

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;

Se vuoi una spiegazione dettagliata puoi seguire il link sottostante Visita https://www.thelearninguy.com/react-native-require-image-using-dynamic-names

Cortesia: https://www.thelearninguy.com


6
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>
  )}
}


4

Per un'immagine dinamica utilizzando require

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')
          }
        
        
        ]

}

quando si preme il pulsante- (seleziono il numero casuale dell'immagine tra 0 e 2))

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

Visualizza

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


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

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

nel mio caso ho provato tanto ma alla fine funziona StyledInput nome del componente immagine all'interno di StyledInput se ancora non capisci fammi sapere


2

Diciamo se hai un'applicazione che ha funzionalità simili a quella della mia. Dove la tua app è per lo più offline e desideri eseguire il rendering delle immagini una dopo l'altra. Di seguito è riportato l'approccio che ha funzionato per me nella versione 0.60 di React Native.

  1. Per prima cosa crea una cartella denominata Resources / Images e posiziona tutte le tue immagini lì.
  2. Ora crea un file chiamato Index.js (in Resources / Images) che è responsabile dell'indicizzazione di tutte le immagini nella cartella Reources / Images .

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

  1. Ora crea un componente chiamato ImageView a tua scelta di cartella. Si possono creare componenti funzionali, di classe o costanti. Ho usato il componente Const. Questo file è responsabile della restituzione dell'immagine a seconda dell'indice.
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. Ora dal componente, ovunque tu voglia eseguire il rendering dinamico delle immagini statiche, usa semplicemente il componente ImageView e passa l'indice.

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


-2

Dovresti usare un oggetto per questo.

Ad esempio, diciamo che ho effettuato una richiesta AJAX a un'API e restituisce un collegamento immagine che salverò con lo stato imageLink:

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


3
per i collegamenti dinamici del percorso dell'immagine, questo non funziona: var img = "../img/icons/"+img_name+"_selected.png"; <br/> <Image source={{uri: img}} resizeMode={'contain'} />
Robert Tomas G IV

4
un trucco per questo, se conosci tutte le varianti di img_name sarebbe andare in questo modo:var images = { 'first': require('../first.png'), 'second': require('../second.png') } <Image source={{uri:images[img_name]}} resizeMode={'contain'} />
Gabriel Lupu

2
Tieni presente che per il suggerimento di @GabrielLupu: stai allocando tutte le immagini nella memoria in questo modo. Dipende dal numero di immagini e dalle loro dimensioni, tuttavia è probabile che si verifichino errori di memoria insufficiente.
Lashae
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.