HerrSiering
HerrSiering

Reputation: 128

How can I set the source of an image dynamically in React native?

I'm playing around with React Native to build a very basic, simple app.

I've got a JSON file which contains some tasks people should accomplish. I randomly choose one task out of the array of options and display the text and the type. The tasks have a type and they have a short text which is the actual task, e.g.:

{
    "text": "Open Wikipedia and read a random article.",
    "type": "Knowledge"
},

What I want to do as well is change the type of the background image that is shown, so that it fits to each task's type. Since I use the image as a background drop behind the text, I would have to change the source part of the image.

It seems as if I can't just paste the task.type.toLowerCase(); or the variable taskStyle into the <Image source> (would be <Image source={require('image!{taskStyle}'}.

In kind of the same way, I would like to hand over the same variable taskStyle to the <View> tag that has a fixed backgroundColor right now as a style, since there should also be a different color for each type of tasks.

Since I have little knowledge about React, I'm pretty sure I don't get a very basic concept, so I don't know how to handle this correctly. Could somebody point me to the correct way of doing this? Any help would be appreciated :)

Here's the whole code for the iOS part:

'use strict';

var React = require('react-native');
var Tasks = require('./data/tasks.json');

var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image,
  StatusBarIOS,
} = React;

var progress = React.createClass({

  render: function() {

    StatusBarIOS.setStyle(1);

    var randomTask = Math.floor(Tasks.length * Math.random());
    var task = Tasks[randomTask];

    var taskStyle = task.type.toLowerCase();

    return (
      <Image
        style={styles.container}
        source={require('image!mind')}
      >
        <View style={[
          styles.textWrapper,
          {
            backgroundColor: 'rgba(11,136,191,0.7)',
          }
        ]}>
          <Text
            style={[
              styles.category,
              styles.text,
            ]}
          >
            {task.type}
          </Text>
          <Text
            style={[
              styles.task,
              styles.text,
            ]}
          >
            {task.text}
          </Text>
        </View>
      </Image>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    resizeMode: 'cover',
    // setting these to null avoids too huge images
    width: null,
    height: null,
  },
  textWrapper: {
    alignItems: 'center',
    backgroundColor: 'transparent',
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  knowledge: {
    backgroundColor: 'rgba(240,200,46,0.8)',
  },
  text: {
    backgroundColor: 'transparent',
    fontFamily: 'Avenir',
    margin: 10,
    textAlign: 'center',
  },
  category: {
    color: 'rgba(255,255,255,0.7)',
    fontSize: 24,
  },
  task: {
    color: '#FFFFFF',
    fontSize: 36,
  },
});

AppRegistry.registerComponent('progress', () => progress);

Upvotes: 5

Views: 3876

Answers (1)

Emanuel Kluge
Emanuel Kluge

Reputation: 705

Tach, der Herr.

Though I haven't fiddled around with the "native" version of React, yet, I have two spontaneous ideas on how to tackle this issue.

I. Keep the images in the built app

If you know the amount of topics/images you're dealing with, you can simple require them all and store them in an object whose property-names reflect your topic names.

var imgTopic1 = require('image!topic1');
var imgTopic2 = require('image!topic2');
…

var topicImages = {
    topic1: imgTopic1,
    topic2: imgTopic2,
    …
};

return (<Image src={topicImages[topic]} … />);

II. Use an external resource

If you want to be able to add more topics/images without having to release an upgrade of the app, you can use an external image-service and construct the URL from the topic.

var imgServiceRoot = 'http://example.com/images/';
var imgUrl = imgServiceRoot + topic + '.jpg';

return (<Image src={{uri: topicImages[topic]}} … />);

Have I forgot something?

Upvotes: 7

Related Questions