React Native - Módulo de requisito de imagen usando nombres dinámicos


84

Actualmente estoy construyendo una aplicación de prueba usando React Native. El módulo de imagen, hasta ahora, ha funcionado bien.

Por ejemplo, si tuviera una imagen nombrada avatar, el siguiente fragmento de código funciona bien.

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

Pero pero si lo cambio a una cadena dinámica, obtengo

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

Me sale el error:

Requiere módulo desconocido "imagen! Avatar". Si está seguro de que el módulo está allí, intente reiniciar el empaquetador.

Obviamente, este es un ejemplo artificial, pero los nombres de imágenes dinámicas son importantes. ¿React Native no admite nombres de imágenes dinámicas?

Reaccionar error nativo con nombre de imagen dinámica


1
Encontré un problema similar con Vue, la respuesta está aquí stackoverflow.com/questions/40491506/…
Alonad

Respuestas:


70

Esto se trata en la documentación en la sección " Recursos estáticos ":

La única forma permitida de hacer referencia a una imagen en el paquete es escribir literalmente require ('image! Name-of-the-asset') en la fuente.

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

Sin embargo, también debe recordar agregar sus imágenes a un paquete de xcassets en su aplicación en Xcode, aunque parece que por su comentario ya lo hizo.

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


1
¿Dónde debo agregar imágenes, estoy usando react native para Android, en la carpeta dibujable?
coderzzz18

2
El enlace anterior es incorrecto, el artículo ahora está en facebook.github.io/react-native/docs/images.html
app_sciences

45
hola, ¿cómo hago si tengo cientos de imágenes que necesito?
chanjianyi

1
@chanjianyi estoy en la misma situación :-(
Mo.

1
"Requerir" no funciona en dispositivos IOS para mí. ¿Alguna idea por qué?
Arthur Medeiros

57

Esto funcionó para mí:

Hice un componente de imagen personalizado que toma un booleano para verificar si la imagen es de la web o se está pasando desde una carpeta local.

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

Si ve el código, en lugar de usar uno de estos:

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

Solo estoy enviando todo require('./images/logo.png')como accesorio. ¡Funciona!


5
Esta respuesta merece más crédito. Funciona absolutamente cuando declaras la declaración require y la pasas como un accesorio. Muchas gracias por su simple explicación, solo deseo que otros sean tan claros.
dazziola

1
La utilería funciona de maravilla. Eso debe indicarse en los documentos oficiales.
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
En el componente principal tengo <CustomImage fromWeb={false} imageName={require(../../assets/icons/${el.img}.png )} /> y esto en el componente secundarioclass CustomImage extends Component { constructor(props) { super(props); } render() { return ( <Image source={this.props.imageName} resizeMode="contain" style={{ height: 24, width: 24 }} /> ); } }
Walter Monecke

2
Genio puro, esto es exactamente lo que estaba buscando :)
Sumit Sahoo

52

RELEVANTE SI HA CONOCIDO IMÁGENES (URL):

La forma en que me abrí camino a través de este problema:

Creé un archivo con un objeto que almacenaba la imagen y el nombre de la imagen:

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

Luego importé el objeto en el componente donde quiero usarlo y simplemente hago mi renderizado condicional así:

import { images } from 'relative/path';

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

<Image source={imgSource} />

Sé que no es la forma más eficiente, pero definitivamente es una solución.

¡Espero eso ayude!


3
Solución ordenada para manejar un conjunto conocido de imágenes
Tedy Kanjirathinkal

1
@TedyKanjirathinkal ¡Me alegro de que haya ayudado!
Walter Monecke

1
Gracias, esto será útil
Truca

@WalterMonecke: obtengo un valor entero si lo hacemos así
sabir

24

Si está buscando una forma de crear una lista recorriendo una matriz JSON de sus imágenes y descripciones, por ejemplo, esto funcionará para usted.

  1. Cree un archivo (para contener nuestra base de datos JSON), por ejemplo, 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. Luego importe los datos en nuestro componente y recorra la lista usando 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>
  )}
/>

¡Buena suerte!


3
Gracias, ¡esto funcionó para mí después de tanta frustración!
Cherucole

11

Como dice la documentación de React Native , todas sus fuentes de imágenes deben cargarse antes de compilar su paquete

Entonces, otra forma en que puede usar imágenes dinámicas es usando una declaración de cambio. Digamos que quieres mostrar un avatar diferente para un personaje diferente, puedes hacer algo como esto:

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

Consulta la merienda: https://snack.expo.io/@abranhe/dynamic-images

Además, recuerda que si tu imagen está en línea no tienes ningún problema, puedes hacer:

let superhero = "spiderman";

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

7

Primero, cree un archivo con la imagen requerida: las imágenes nativas de React deben cargarse de esta manera.

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

Ahora importe todos sus activos

App.js

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

Ahora puede usar su imagen como un valor interpolado donde imageValue (proveniente del backend) es el mismo que el archivo local con nombre, es decir: 'homeandgarden':

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

Buena solución, ¡me ayudó mucho! Tks.
Fryla- Cristian Marucci

¡Sin preocupaciones! No pude encontrar una buena solución aquí, así que se me ocurrió la mía propia :) Me alegro de haber ayudado.
HannahCarney

5

Parte importante aquí: no podemos concatizar el nombre de la imagen dentro del requisito como [require ('item' + vairable + '. Png')]

Paso 1: Creamos un archivo ImageCollection.js con la siguiente colección de propiedades de imagen

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

Paso 2: Importe la imagen en su aplicación y manipule según sea necesario

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;

Si desea una explicación detallada, puede seguir el enlace a continuación Visite https://www.thelearninguy.com/react-native-require-image-using-dynamic-names

Cortesía: 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

Para el uso de imágenes dinámicas 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')
          }
        
        
        ]

}

cuando presione el botón- (selecciono el número aleatorio de la imagen entre 0-2))

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

ver

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

en mi caso lo intenté mucho pero finalmente funcionó StyledInput imagen del nombre del componente dentro de StyledInput si aún no lo entiendes, avísame


1

Di si tienes una aplicación que tiene una funcionalidad similar a la mía. Donde su aplicación está mayormente fuera de línea y desea renderizar las imágenes una tras otra. Luego, a continuación, se muestra el enfoque que funcionó para mí en React Native versión 0.60.

  1. Primero cree una carpeta llamada Recursos / Imágenes y coloque todas sus imágenes allí.
  2. Ahora cree un archivo llamado Index.js (en Recursos / Imágenes) que es responsable de indexar todas las imágenes en la carpeta Recursos / Imágenes .

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

  1. Ahora cree un componente llamado ImageView en la carpeta que elija. Se puede crear componente funcional, de clase o constante. He usado el componente Const. Este archivo es responsable de devolver la Imagen según el Índice.
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. Ahora, desde el componente donde desee renderizar las imágenes estáticas dinámicamente, simplemente use el componente ImageView y pase el índice.

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


-2

Deberías usar un objeto para eso.

Por ejemplo, digamos que hice una solicitud AJAX a una API y devuelve un enlace de imagen que guardaré en el estado como imageLink:

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


3
para enlaces de ruta de imagen dinámica, esto no funciona: var img = "../img/icons/"+img_name+"_selected.png"; <br/> <Image source={{uri: img}} resizeMode={'contain'} />
Robert Tomas G IV

3
un truco para esto, si conoce todas las variantes de img_name sería ir de esta manera:var images = { 'first': require('../first.png'), 'second': require('../second.png') } <Image source={{uri:images[img_name]}} resizeMode={'contain'} />
Gabriel Lupu

2
Tenga en cuenta que para la sugerencia de @GabrielLupu: De esta manera, está asignando todas las imágenes en la memoria. Depende de la cantidad de imágenes y sus tamaños, sin embargo, es probable que experimente errores de memoria.
Lashae
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.