I can't dynamically pass relative img src route in React + Webpack with this.props.
This is a very simplified part of the parent component. It iterates some data list and generates ImgComponents passing props. Here is only tiny part of it:
return (
<div>
<ImgComponent srcProp={videolist.anotherImage.src} />
</div>
);
The ImgComponent has:
render() {
return (
<div>
<img src={`${this.props.srcProp}`} />
</div>
);
}
In console I get exactly the same route as i pass with this.props.srcProp, but it would not find the folder and the img there. As if webpack does not load the img.
Here is the console:
<img src="framework/assets/images/cover-bigbuckbunny.png" class="_2WcF9ZmcK-9bQX6jKk18Y_" data-reactid=".0.1.1:$comedy.0.0.$0.0.0.0">
No matter what route i indicate, the img is never found in the folder.
Here is the webpack config for png:
{ test: /\.png$/, loader: "url-loader?mimetype=image/png" }
BTW. It works fine if i require the file, like:
<img src={require ('framework/assets/images/cover-bigbuckbunny.png')} />
or indicate some remote route, like http://route.to.some.img
Seems like webpack does not load it. What should i do to dynamically load local img files by dynamically passing src with {this.props.src} ? As I can see, the loader loads img fine if i indicate the file with require. But this way i cannot do it dynamically, as require does not take variables.
What I managed to do is to require('../../assets/images/myFirst.img') in the object, containing the routs to the locally stored files:
in playlist.js
export default (
{
cartoons: [{
images: {
poster: require('../../assets/images/myFirst.png')
},
streams: [{
type: 'mp4',
url: 'http://media.w3.org/2010/05/bunny/movie.mp4'
}]
});
Then I work with this list as with any object:
import playlist from '../../playlist';
and iterate this object in a usual manner. The image will be there.
Webpack will not traverse your code to find and convert all possible references to files.
Consider following code:
<img src={'/foo/bar/baz.jpg'} />
It is your responsibility (perhaps using a build target) to ensure that baz.jpg is copied into the foo/bar directory under your web app root.
Related
With create-react-app and JavaScript/TypeScript, I understand I'm able to "import" an SVG as noted below. How may I do so with ReasonML?
import { ReactComponent as Logo } from './logo.svg';
function App() {
return (
<div>
{/* Logo is an actual React component */}
<Logo />
</div>
);
}
Create React App uses webpack to transform SVG files into React components. If you’re using Reason with CRA, then all you need to do is provide a binding to the generated component. However, CRA will only transform the SVG into a component if the import statement is written exactly a certain way, which isn't how BuckleScript outputs import statements. (There's a GitHub issue about it here.) You have to import it with raw JavaScript and then bind to the imported value:
%bs.raw
{|import {ReactComponent as _Logo} from "./logo.svg"|};
module Logo = {
[#react.component] [#bs.val] external make: unit => React.element = "_Logo";
};
/* And we can use it like a regular component: */
[#react.component]
let make = () =>
<div>
<Logo />
</div>;
According to the CRA docs:
The imported SVG React Component accepts a title prop along with other props that a svg element accepts.
For any of the other props you want to use, you'll have to add them to your external binding.
If you're not using CRA, then you'll need to configure your bundler to do the same transformation. I'm not familiar with the internals of CRA, but this seems to be the relevant code from its webpack configuration.
We can use SVGR to handle the webpack loading and then import the module as we normally would.
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
module: {
rules: [
//...
{
test: /\.svg$/,
use: ['#svgr/webpack'],
},
],
},
//...
};
module Logo = {
#bs.module(`../../../../src/img/logo.svg`) #react.component
external make: {.} => React.element = "default"
}
...
<Logo /> // works
source: https://blog.logrocket.com/how-to-use-svgs-in-react/
I am the author of another solution that doesn't involve webpack.
It's a tool that can transform your svg files directly into .re files: https://github.com/MoOx/react-from-svg
This can create files for react (dom) or react-native(-web) (=> files generated use react-native-svg).
Feel free to try it :)
For example you can do (when the tool is installed from npm)
$ react-from-svg src/SVGs src/SVGs/components --with-native-for-reason --remove-fill
This will turns the files from svg/SVGs into React components into src/SVGs/components compatible for React Native with the Reason syntax.
The last option remove all svg fill props so you can use them as icons.
Note that the generated components accept width, height & fill props so you can adjust them when used.
Last bonus: since webpack is not involved, you can use this transformation only when you update your SVGs files & use this code directly with a Node runtime (JSX from Reason gets removed when converted to JS so the code can be consumed directly via Node without any transformation - which can be handy for tiny static sites/pages).
I have given path of images in my js file like this image: "/images/mussels.jpg", and imported file in a component in react app. everything looks fine in localhost/3000 but when i uploaded app on web, images path is not right and images are not shown on the web. also when I check in console, there is style attribute empty. but I gave style in ,my css file separately.
This is my SampleFishes.js file with data like this:
const sampleFishes = {
fish1: {
name: "Pacific Halibut",
image: "/images/hali.jpg",
desc: "Everyones favorite white fish. We will cut it to the
size you need and ship it.",
price: 1724,
status: "available"
}
Export default SampleFishes;
Then in Fish component:
image is imported via this.props like this below:
<img
src={this.props.details.image}
alt={this.props.details.name}
className="img"
/>;
which are coming through App.js and Samplefishes are imported there like this:
import sampleFishes from "../SampleFishes";
and
{
Object.keys(this.state.fishes).map(key => (
<Fish
key={key}
details={this.state.fishes[key]}
ordkey={key}
addToOrder={this.addToOrder}
/>
));
}
In console.log, HTML element shows image path like this:
<img src="/images/hali.jpg" alt="Pacific Halibut" class="img" style="">
But image on the web is not shown. I have given style in css file to .img className as
.menu-fish .img {
float: left;
width: 150px;
margin-right: 1rem;
}
One guess here is that you have to change your image paths to "./images/mussels.jpg" when you deploy your app to the server. This is my best guess on the little info that we've got here =)
I figured it out. In build folder, there is index.html file which has path to css like this href="/Shop-Fish/static/css/main.4b89f08f.chunk.css"
So that means images will have the path like the same as src="/Shop-Fish/images/prawns.jpg" which in local host case was only src="/images/prawns.jpg" but when it was build for github gh-pages, it attached the repo name with it in all refs and images also needed the same repo name ref first and then images path. So thankyou all who tried to solve my query.
I am having trouble locating the location of my images with react redux.
I am creating a react movie card that looks like this:
http://react-movie-cards.drminnaar.me/
My state is in the redux store.
My file structure is this.
the state is located at MovieList-reducer.js and I mapped it at MovieCard.js file.
why is it having an error like this:
×
←→1 of 6 errors on the page
Error: Cannot find module '../images/Kingsglaive_Final_Fantasy_XV.jpg'
▶ 32 stack frames were collapsed.
and have this in the terminal:
./src/Movies/MovieCard.js
Critical dependency: the request of a dependency is an expression
Please help me locate the file of the images.
you can find and clone my repo in https://github.com/bradrar/movie-cards and yarn start or npm start
I just need to locate the images and map it like so:
<img className="card-img-top" src={require(props.movie.imageUrl)} alt="" />
I know I am very close because I tried
<img className="card-img-top" src={require("../images/Ghost_In_The_Shell_2_0.jpg")} alt="" />
and it looks like this:
See my pull request here. Because webpack needs to know all your dependencies at build time, it's not possible to use require in a dynamic context. Use require.context() to build a context of all your images, and then reference them using that context.
First, change your references to use ./ instead (As because we're loading that folder into context, that essentially becomes the root ./):
{
"id": 100,
"title": "Kingsglaive",
...
"imageUrl": "./Kingsglaive_Final_Fantasy_XV.jpg"
},
And then in your movie card, create the context. (React will read through the folder at build time, and then give you the ability to access them using the context created):
const movieImages = require.context("../images/", true, /\.jpg$/);
const MovieCard = (props) => {
return (
...
<img className="card-img-top" src={movieImages(props.movie.imageUrl)} alt="" />
)
}
To be clear:
<img src={require('../styles/myimage.jpg')} />
works fine. But I want to get this path dynamically as a string from api. In my parent component I fetch it and pass to child:
<img src={require(this.props.image)} />
In this case this.props.image is the same as '../styles/myimage.jpg'. But it does not work for me and throw this error "Uncaught (in promise) Error: Cannot find module "."
How can I fix it?
The directory tree is (I am trying to fetch myimage.jpg from image.js)enter image description here:
And webpack config: enter image description here
Do a simple test, move styles path with contains yours jpg files to same path of your component and try this path in props:
props.image = './styles/myimage.jpg'
then
<img src={require(this.props.image)} />
In addition to the comment what you can do is in your render method try this :
if (!this.props.image) return false;
Problem with dynamic loading of image resources within a loop/list.
I have all my static local resources required as such:
assets/images.js
const images = {
appLogo: require('./app-logo.png'),
cardOne: require('./cards/card-1.png'),
cardTwo: require('./cards/card-2.png'),
...
cardForty: require(./cards/card-40.png)
}
export default images;
Then in my list screen:
...
import images from '../assets/images';
...
renderListItems(item) {
const image_name = `images.card${item.cardName}`;
console.log(image_name); // images.cardOne, images.cardTwo etc..
return (
<ListItem avatar>
<Thumbnail square size={80} source={image_name} /> // This is nativebase component which wraps the RN image component
<Body>
<Text>{item.name}</Text>
</Body>
<Right>
<NBIcon name="arrow-forward" />
</Right>
</ListItem>
);
}
...
No resources get loaded. Yet if I change the source={image_name} to source={images.cardOne} directly (where images.cardOne is the exact same as image_name variable on the first iteration) it works - except for the fact that they all have the same image.
I also tried using {{ uri: image_name }} syntax but nothing happens there too.
There doesn't seem to be any solution to this, other than creating a massive switch statement
Well that's because image_name is a string with the value of images.cardOne whereas images.cardOne is also a string but with the value of the actual path of the images in your file system (e.g ./app-logo.png). So if you want to load images object dynamically to image_name, you should use the bracket notation like so:
const image_name = images[`card${item.cardName}`];
That way image_name will now point to the path of your images (e.g ./app-logo.png).