0

In React Native (I'm very new to React) I have a javascript function that returns an array in a variable called myResult. Printed in the terminal it shows:

 Array [
 25,
 25,
 20,
 10,
 5,
 5,
]

which I add to the state with

    this.setState({resultArray: myResult});

Then, in the state I have an array like so:

   this.state = {
      foodList: [
    {id: "25", 
    src: `"./images/banana25.png"`
  },
    {id: "20",
    src: `"./images/banana20.png"`
  },
    {id: "15",
    src: `"./images/apple15.png"`
  },
    {id: "10",
    src: `"./images/mango10.png"`
  },
    {id: "5",
    src: `"./images/steakNeggs5.png"`
  },
   }

Using the resultArray I want to show an image in a view for each item, the image corresponding to the id which matches each array item.

  <View style={{height: 318, flexDirection: "row" }}>

   {this.state. resultArray.map((item, key) => {
      let src = this.state.foodList.item.src
     return (
      <Image key={key} style={{flexDirection: "row" }} source={require({src})} />
     );
  })}

 </View>

Obviously, that doesn't work as I don't have the syntax right for src.

Can someone show me the correct syntax to get the src from the foodList array?

Also, according to the docs, using the index as the key works but is frowned upon, but since the resultArray can (and in this case, does) hold identical numbers/strings, using the array items, I assume, is not possible. Would using Math.random() be a way to create a key, considering the the output would only be making 1-10 Image components?

5 Answers 5

1

I believe the line should be this:

<View style={{height: 318, flexDirection: "row" }}>

   {this.state.resultArray.map((item, key) => {
      let src = this.state.foodList.find(food => +food.id === item).src;
     return <Image key={key} style={{flexDirection: "row" }} source={uri: src)} />;
  })}

 </View>

Also, using Math.random for key is equally frowned upon. Please read https://reactjs.org/docs/reconciliation.html

Sign up to request clarification or add additional context in comments.

2 Comments

What does the + do?
It coerces a string to a number.
0

If the image is locally saved it's <Image source={require('./path/to/image')}. If you need to load an image from an url it's: <Image source={{uri: 'https://www.url.to/image.png'}}.

So in your case, if the image isn't in the project folder, it's:

<Image key={key} style={{flexDirection: "row" }} source={{uri:src}} />

3 Comments

Sorry. Forgot to specify that they are local files, so require is needed, not uri.
Is it saved inside the project folder or inside the device? If you download it from somewhere else, even if it's local you need to specify the image uri. Note that in android you need to use 'file://path/to/image.jpg' while on ios it's "path/to/image"
I'm coding on a Mac and testing on a physical iPhone. This works: <Image source={require("./images/aphotoOfMyMom.png")} style={{ width: 45, height: 318, flexDirection: "row" }} />
0

After a bit of fiddling to get all the braces and brackets right, I came up with:

    <View style={{height: 318, flexDirection: "row" }}>
      {this.state.resultArray.map((item, key) => {
      let src = this.state.foodList.find(food => +food.id === item).src;

       console.log(src);

      })}
     </View>

That gave me the expected result in the console/Terminal:

 "./images/banana25.png"
 "./images/banana25.png"
 "./images/banana25.png"
 "./images/banana20.png"
 "./images/coconut2.5.png"
 "./images/pineapple0.5.png"
 "./images/pineapple0.5.png"

But with the image tag/component added:

 {this.state.resultArray.map((item, key) => {
  let src = this.state.foodList.find(food => +food.id === item).src;
  return(
  <Image key={key} style={{flexDirection: "row" }} source={require({src})} />
  );

})}

I get an error in the terminal:

 Critical dependency: the request of a dependency is an expression

and in the iPhone using the Expo app I get:

iPhone error message

Not sure what src: src means or, considering the terminal is showing the correct path, why the Image tag is throwing an error.

Comments

0

OK. It now works. I changed the foodList array slightly so that the items were listed as:

 {id: "25", 
    src: require("./images/banana25.png"),
  },
    {id: "20",
    src: require("./images/banana20.png"),
  }, 
  etc, etc.

Then I changed the component to:

 <View style={{height: 318, flexDirection: "row" }}>
    {this.state.resultArray.map((item, key) => {
    let src = this.state.foodList.find(food => +food.id === item).src;
    return <Image key={key} style={{flexDirection: "row" }} source={src} />;
   })}

  </View>

Notice that it's "source={src}" and not "source={{src}}".

This was based on the answer I found to a parallel issue with using variable in a source={require()} as opposed to a source={uri:

Why can't string variable be used in <Image source={}/>? (React Native)

where it's shown how to get around the fact that variables are not allowed in a require.

Adding in a: console.log(src) gives me the indexes of the id/src object, so somehow the src string is not going through, but the image require is.

So, not exactly sure how/why, but making src into a non-string require("./path) and referencing that, works.

Comments

0

To get the correct src from foodList, use Array find()

this.state.resultArray.map((id, index) => {
  const { src } = this.state.foodList.find(item => item.id === id);
  return (
    <Image key={index} style={{flexDirection: "row" }} source={require(src)} />
  );
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.