I have problems and need help with rendering an image in React. The problem is that this image is stored locally, and the URL to this image is retrieved from database with Axios.get() along with some other data. All data is showing up fine, but cannot render that image.
class Lesson extends Component {
state = {
lesson: null
};
componentDidMount() {
Axios.get("https://localhost:44372/api/Lesson/lesson/" +
this.props.location.pathname.substring(
this.props.location.pathname.lastIndexOf("/") + 1)
).then(response => {
console.log("API Response", response);
const newLesson = response.data;
this.setState({
lesson: newLesson,
});
});
}
render() {
return (<div>
<h2 style={{ textAlign: "center" }}>{this.state.lesson.title}</h2>
<p>{this.state.lesson.text}</p>
<p>{this.state.lesson.field1}</p>
<img src={this.state.lesson.img} //<-----here
alt="none"
style={{
verticalAlign: "middle",
display: "block",
margin: "auto",
marginLeft: "auto",
marginRight: "auto"
}}
/>
<div>);
In this way that image does not show up.
Error that I encounter is: Not allowed to load local resource: file:///D:/Project/FrontEnd/platform/src/images/python_img.PNG
The only way that I can get that img is to insert like this manually, but this is not what I want:
<img src={require("D:\\Project\\FrontEnd\\platform\\src\\images\\python_img.PNG")}
I thought that the problem is in componentDidMount(), as I was getting an undefined value at start, but later I just provided the same path from parent page (just to check) and the problem is the same.
I am doing something wrong...
Is a way to provide as image source a variable?
If the images itself is bundled in your react app, then its not going to work like you expect.
require() only accepts static
Things you can do
1.Render conditionally
const images = {
image1: require('./image1.jpg'),
image2: require('./image2.jpg'),
};
Then in your app
<img src={this.state.lesson.img === 'something_unique' ? images.image1 : images.image2} //<-----here
alt="none"
style={{
verticalAlign: "middle",
display: "block",
margin: "auto",
marginLeft: "auto",
marginRight: "auto"
}}
/>
2.Or if your using a bundler, you can get the public URL and append it.
<img src={process.env.PUBLIC_URL + this.state.lesson.img} />
Related
I have following react component:
var ForumActivityTimeLine = React.createClass({
componentDidMount: function () {
this.showActivityLineChart()
},
showActivityLineChart() {
const lineChartSpec = getForumActivityLineChart(this.props.data.frequency)
const opt = {
renderer: "canvas",
actions: false
};
vegaEmbed('#ForumActivityLineChart', lineChartSpec, opt)
},
render() {
return (
<span>
<h5 style={{ textAlign: "center", fontWeight: "bold", display: "block", paddingTop: '2em' }}> Forum Activity Timeline</h5>
<div className="d-flex justify-content-around" style={{ paddingTop: "0.5em" }}>
<div id='#ForumActivityLineChart'></div>
</div>
</span>
)
}
})
vegaEmbed line is trying to render a line chart in the div with id ForumActivityLineChart, but it gives me following error:
embed.ts:296 Uncaught (in promise) Error: #ForumActivityLineChart does not exist
at Kn (embed.ts:296:11)
at Jn (embed.ts:259:16)
Here is the error desscription in console:
In chrome dev tools console, you can see that the corresponding div element does exist (ignore setTimeout call in snapshot, I thought if I can dirty set some timeout to let the component render first):
Here is another screenshot, where debugger stops before throwing exception:
PS: I am working on legacy react app, thats why I have var and componentDidMount.
You should not include # in the id-attribute.
Replace
<div id='#ForumActivityLineChart'></div>
with
<div id='ForumActivityLineChart'></div>
I was following a tutorial on youtube (https://youtu.be/3HNyXCPDQ7Q) for creating a portfolio website. I hosted the website using Netlify, 20 days later when I revisited the website, the website was just a blank screen. When I tested again on localhost, the problem was with sanity. When I connected to sanity, the screen would go blank.
Now the problem is that the regular website content is visible, but the data from sanity is not being fetched to the react app.
I have added some documents in the abouts schema via the sanity gui.
Abouts Schema:
export default {
name: "abouts",
title: "Abouts",
type: "document",
fields: [
{
name: "title",
title: "Title",
type: "string",
},
{
name: "description",
title: "Description",
type: "string",
},
{
name: "imgUrl",
title: "ImgUrl",
type: "image",
options: {
hotspot: true,
},
},
],
};
About.jsx code:
import React, { useState, useEffect } from "react";
import { motion } from "framer-motion";
import "./About.scss";
import { urlFor, client } from "../../Client";
import { AppWrapper } from "../../wrapper/";
const About = () => {
const [abouts, setAbouts] = useState([]);
const querySelector = async () => {
const query = '*[_type == "abouts"]';
const aboutsQuery = await client.fetch(query);
aboutsQuery.then((data) => setAbouts(data));
};
useEffect(() => {
querySelector();
}, []);
return (
<>
<motion.div
className="app__about-header"
whileInView={{ x: [1000, 0] }}
transition={{ duration: 1 }}
viewport={{ once: true }}
>
<h1 className="head-text">
<span>About</span> Me
</h1>
</motion.div>
<motion.div
className="app__about-desc"
whileInView={{ opacity: [0, 1] }}
transition={{ duration: 1 }}
viewport={{ once: true }}
>
<h3 style={{ marginBottom: 10 }}>Who I am?</h3>
<p className="p-text">
Some text here.
</p>
</motion.div>
<motion.div
style={{ marginTop: 40 }}
whileInView={{ x: [-1000, 0] }}
transition={{ duration: 1 }}
viewport={{ once: true }}
>
<h2 className="head-text">
What I <span>Love to do?</span>
</h2>
</motion.div>
<div className="app__profiles">
{abouts.map((about, index) => {
return (
<motion.div
whileInView={{ opacity: [0, 1] }}
whileHover={{ scale: 1.1 }}
transition={{ duration: 1, type: "tween" }}
className="app__profile-item"
key={index}
viewport={{ once: true }}
>
<img src={urlFor(about.imgUrl)} alt={about.title} />
<h2 className="bold-text" style={{ marginTop: 20 }}>
{about.title}
</h2>
<p className="p-text">{about.description}</p>
</motion.div>
);
})}
</div>
</>
);
};
export default AppWrapper(About, "about", "app__whitebg");
This Client.js file will connect to the sanity CMS.
Client.js code:
import SanityClient from "#sanity/client";
import imageUrlBuilder from "#sanity/image-url";
export const client = SanityClient({
projectId: "hard coded value added here",
dataset: "portfoliodataset",
apiVersion: "2022-08-11",
useCdn: true,
token: "token value here",
});
const builder = imageUrlBuilder(client);
export const urlFor = (source) => builder.image(source);
I have tried the env variable as well in client.js file.
for eg. projectId: process.env.REACT_APP_SANITY_PROJECT_ID
and I have tried the hard coded values as well. Both don't seem to work.
Note that I have also added the localhost:3000 and the website url in the CORS origin.
Please help me, I am stuck on this problem for a few days now.
I dont know whether you are struck in this or not but giving you reply in case in future if someone struck at this point they can fix it. I also faced the same issue and strucked for the time being and later I realized the issue. The issue is you can't give some random name to the dataset
export const client = SanityClient({
projectId: "hard coded value added here",
dataset: "portfoliodataset",
apiVersion: "2022-08-11",
useCdn: true,
token: "token value here",
});
Here in this dataset field you have to give the dataset name which is in sanity.json file. Hope it would help you
I was facing same issue and I was able to fix it by doing following stuff:
Installing dotenv node package
Moving .env file to frontend_react folder. (I accidentally created it under src folder)
I hope that it would help you too.
Make sure you have import the key and run the sanity client on your localhost
I had exactly the same problem, in the same tutorial. make sure first you have internet connection, then try restarting everything even with internet on.
Its basically a network issue not withstanding any other possible cause of error, but you could give it time then later refresh the react app as well as the sanity client.
Also you could try adding some more code to give the compiler something new to compile, some how the app will load sanity.
Check your sanity.json or sanity.config.js file (if you are using vite) and make sure the dataset you are using is the correct one. It has to match what you have in the client.js file
I had the same issue
I was able to get Flickity working as expected. But for some reason when I made it to where the image sources are fetched from an external database, the images stopped loading properly and broke flickity.
render() {
const image_urls = this.state.image_urls.map(url => url) // These images urls were fetched using axios.
return(
<div className="featured-work" id="featured_work">
<div className="title"><div className="text">FEATURED WORK</div></div>
<div className="main-carousel" data-flickity='{ "wrapAround": true, "imagesLoaded": true, "groupCells": 1, "autoPlay": 7000 }'>
{
image_urls.map(url => {
return <div style={{backgroundImage: `url(${url})`, backgroundColor: 'orange', backgroundSize: 'contain', backgroundRepeat: 'no-repeat', height: '400px', width: '599px', marginLeft: '48px'}} />
})
}
</div>
<div className="button-container">
<form action={this.state.behance_link} target="_blank" rel="noopener noreferrer">
<button className="button button--pan"><span>VIEW FULL PORTFOLIO</span></button>
</form>
</div>
</div>
)
}
This is what the API call looks like for fetching the images urls/sources:
const google_sheet_id = "1dezRYzkCZ8VrfsbO2EKVoF9D_hIHsKAF_BuI7b83phA";
const selection_1 = "G5";
const selection_2 = "G21";
axios.get(`https://tofufx-backend.herokuapp.com/google_sheets/${selection_1}/${selection_2}/${google_sheet_id}?api_key=${process.env.REACT_APP_TOFU_BACKEND_API_KEY}`)
.then(response => {
const image_urls_unfiltered = response.data.values.map(row => {
return row[0]
})
const image_urls = image_urls_unfiltered.filter(url => {
return (typeof url === 'string');
})
this.setState({image_urls});
})
I tried to replace the images as divs with backgrounds which didn't fix the problem
This is my first question here so I hope to explain it correctly.
I have imported a datepicker element and im trying to override a class property by doing the following:
const useStyles = makeStyles({
testingWidthLimit: {
width: '180px !important',
minWidth: '180px !important',
maxWidth: '180px !important',
},
};
const { testingWidthLimit } = useStyles();
<InputDate
className={testingWidthLimit}
{other properties here}
/>
I cannot post a picture due to my starter reputation, but this is what's rendered on the screen:
<div class="sc-gXZlrW ikzFYF makeStyles-testingWidthLimit-3">
<div class="react-date-picker react-date-picker--closed react-date-picker--enabled">
<div class="react-date-picker__wrapper">
(the rest goes here but that is not important)
</div>
</div>
</div>
oh the class "react-date-picker__wrapper" the property "min-width: 264px" is still there
As you can see, I've tried every property I know of and still won't override the child property. I do not have access to the InputDate code and I have to use it.
I tried using !important (with or without space as I've seen on some other questions) and one property at a time and that is still not working, can anyone tell me what am I missing?
Edit1: on the first div, my class is being applied and all of the properties are there with the !important tag.
Below is the syntax you need to override the min-width of the react-date-picker__wrapper descendant of the element with the testingWidthLimit CSS class:
const useStyles = makeStyles({
testingWidthLimit: {
"& .react-date-picker__wrapper": {
minWidth: 180,
}
},
};
If you need to set min-width on the descendant and on the testingWidthLimit element itself, then you would want the following:
const useStyles = makeStyles({
testingWidthLimit: {
minWidth: 180,
"& .react-date-picker__wrapper": {
minWidth: 180,
}
},
};
Related documentation:
https://cssinjs.org/jss-plugin-nested?v=v10.5.0#use--to-reference-selector-of-the-parent-rule
https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator
I'm working in react and basically I want to make an button with tooltip, right now I'm making tooltip. I'm changing css display property in order to make it visible or not during mouse enter and leave. But there is an error and I don't know what to do...
Here is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import Style from 'style-it';
var Ink = require('react-ink');
import FontIcon from '../FontIcon/FontIcon';
var IconButton = React.createClass({
getInitialState() {
return {
iconStyle: "",
style: "",
cursorPos: {},
};
},
extend(obj, src) {
Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
return obj;
},
Tooltip(props) {
var style = {};
if (this.tooltipDisplay) {
style.display = "block";
} else if (!this.tooltipDisplay) {
style.display = "none";
};
return <div className="tooltip" style={style}>{_props.tooltip}</div>;
},
showTooltip(){
this.tooltipDisplay = true;
},
removeTooltip(){
this.tooltipDisplay = false;
},
render() {
var _props = this.props,
tooltip = this.Tooltip,
opts,
tooltipDisplay = false,
disabled = false,
rippleOpacity,
outterStyleMy = {
border: "none",
outline: "none",
padding: "8px 10px",
"background-color": "red",
"border-radius": 100 + "%",
cursor: "pointer",
},
iconStyleMy = {
"font-size": 12 + "px",
"text-decoration": "none",
"text-align": "center",
display: 'flex',
'justify-content': 'center',
'align-items': 'center',
},
rippleStyle = {
color: "rgba(0,0,0,0.5)",
};
if (_props.disabled || _props.disableTouchRipple) {
rippleStyle.opacity = 0;
};
this.setState({
iconStyle: _props.iconStyle
});
this.setState({
style: _props.style
});
if (_props.disabled) {
disabled = true;
};
if (this.state.labelStyle) {
iconStyleMy = this.state.iconStyle;
};
if (this.state.style) {
outterStyleMy = this.state.style;
};
if (_props.href) {
opts.href = _props.href;
};
var buttonStyle = this.extend(outterStyleMy, iconStyleMy);
return(
<Style>
{`
.IconButton{
position: relative;
}
.IconButton:disabled{
color: ${_props.disabledColor};
}
.btnhref{
text-decoration: none;
}
`}
<a {...opts} className="btnhref" >
<tooltip text={this.props.tooltip} position={this.options} />
<button ref="button" className={"IconButton" + _props.className} disabled={disabled} style={buttonStyle}
onMouseEnter={this.showTooltip} onMouseLeave={this.removeTooltip} >
<Ink background={true} style={rippleStyle} opacity={rippleOpacity} />
<FontIcon className={_props.iconClassName}/>
</button>
</a>
</Style>
);
}
});
ReactDOM.render(
<IconButton href="" className="" iconStyle="" style="" iconClassName="face" disabled="" disableTouchRipple="" tooltip="aaaaa" />,
document.getElementById('app')
);
In console I'm getting this error:
Uncaught RangeError: Maximum call stack size exceeded
at defineRefPropWarningGetter (App.js:1053)
at Object.ReactElement.createElement (App.js:1220)
at Object.createElement (App.js:3329)
at Constructor.render (App.js:43403)
at App.js:15952
at measureLifeCyclePerf (App.js:15233)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (App.js:15951)
at ReactCompositeComponentWrapper._renderValidatedComponent (App.js:15978)
at ReactCompositeComponentWrapper._updateRenderedComponent (App.js:15902)
at ReactCompositeComponentWrapper._performComponentUpdate (App.js:15880)
I can't find out what's wrong. I know it might be something about calling a function which in turn calls another function. But I can't see anything like this in my code and I'm not sure if it's all about it. Thanks for help :)
The problem is you are calling setState from inside your render function. State changes should only happen as a result of something changing: user clicked on a button, the browser window was resized, a picture was taken, etc.
Never ever ever ever update the state while rendering (repeat that last sentence 20 times and never forget it).
Here is the problem code:
render () {
...
this.setState({
iconStyle: _props.iconStyle
});
this.setState({
style: _props.style
});
...
}
The above code would cause an infinite loop of sorts because setState causes render to be called. Since iconStyle and style are props, and props cannot change, you should use those props to build your initial state.
getInitialState() {
return {
iconStyle: this.props.iconStyle,
style: this.props.style,
cursorPos: {},
};
}
Later, if someone clicks a button and you want the iconStyle to change, you would create a click handler which updates your state:
handleClick () {
this.setState({
iconStyle: 'clicked'
});
}
This would cause your component to be rerendered and the new state would be reflected.
Think of your "state" as someone cooking and we are going to take photographs of them cooking. The initial state is "eggs cracked: no, flour poured: no, veggies chopped: no", and you take a picture of this state. Then the chef does something - cracks the eggs. The state has now changed, and you take a picture of it. Then she cuts the veggies. Again, the state has changed and you take a picture.
Each photograph in the analogy represents your "render" function - a snapshot of the "state" at a particular point in time. If every time you took a photograph the flour got poured, well we would have to take another picture because the flour was just poured. Taking another picture would cause more flour to get poured so we'd have to take another picture. Eventually you'd fill the kitchen to the ceiling with a celiac's nightmare and suffocate everybody in the room. You'd also run out of film or hard disk space on your camera.
Thanks to #RyanWheale I noticed my mistake.
In my render function I was returning a button element which called a function which changed a certain state. The returned button looked like this:
<button onclick={this.edit()} className="button-primary">Edit</button>
And my edit function changes some state and looks like this:
edit: function () {
this.setState({editing: true});
}
So, I my mistake is that I, accidentally, typed the parenthesis after this.edit. So, when the button element was being rendered, the edit function was actually called and chaos happened. Now, when I wrote
<button onclick={this.edit} className="button-primary">Edit</button>
instead of
<button onclick={this.edit()} className="button-primary">Edit</button>
it worked flawlessly.
I hope I help someone save hours of his precious life.
Cheers :)
I faced the same problem, I had installed "reactime" extension and that extension caused me this problem. Removing that extension from my chrome, solved the issue.
I got 'Maximum call stack size exceeded', and similar errors because of framer-motion API dependency, version bigger than 4.1.17 (today's version is 5.5.5). I don't figured out why yet.
For the same extensions also, got some weird errors like 'window.webkitStorageInfo' is deprecated, and similar bugs.
I had the same error in my SPFX project while running Gulp Serve. I deleted the newly added reference in my config.json file and it worked.
More details: https://fixingsharepoint.blogspot.com/2022/04/rangeerror-maximum-call-stack-size.html