I'm not certain if this is specific to React or the build chain inside SPFx, but I'm having issues setting a background image on a div dynamically. I receive the URL from an API call to SharePoint and use the below code to generate a simple site card with the site logo and title.
const Site = (props: SpSite) => {
const {Title, Url, BannerImageUrl, Acronym, BannerColor} = props;
const hasLogo = BannerImageUrl && BannerImageUrl.length > 0;
const logoUrl = hasLogo ? encodeURI(BannerImageUrl) : null;
const logoStyle: React.CSSProperties = hasLogo ? {backgroundImage: `url('${logoUrl}')`} : {backgroundColor: BannerColor};
const siteLogo = <div className="site-logo" style={logoStyle}>{!hasLogo && Acronym}</div>;
return (
<div className="site-card">
<a href={Url}>
<div>{siteLogo}</div>
<div className="site-text">
<div>{Title}</div>
</div>
</a>
</div>
);
};
When the URL is in the format https://tenant.sharepoint.com/image.jpg everything works as expected and the background image is set properly on the generated HTML. When the URL has the format of https://sitename.com/GetLogo?id='RandomGUID' the attribute
style="background-image: url('https://SomeImageUrl')" doesn't get created on the resulting div. I can't figure out if this is being stripped out somewhere in the build chain or if React isn't handling it properly. I can browse directly to the GUID based image URL and it renders just fine.
Turns out that this was a simple single vs double quote issue. Switched url('${logoUrl}') to url("${logoUrl}")and all works as expected.
Related
To set the background cover using TailwindCSS I have extracted the color from bookId (10 digit number) inside useEffect. The color gets updated and component re-renders with the updated color value but the background color on the rendered page is still the same of its parent div.
const colors = [
'from-red-500',
'from-orange-500',
'from-yellow-500',
'from-green-500',
'from-cyan-500',
'from-blue-500',
'from-indigo-500',
'from-violet-500',
'from-purple-500',
'from-pink-500',
]
function BgCover(props) {
const [color, setColor] = useState(null)
const router = useRouter()
useEffect(() => {
const id = router.query.bookId
const index = id.slice(-1) //extract the index from bookId
const bgColor = colors[index]
setColor(bgColor)
}, [])
return (
<Fragment>
{color ? (
<div className='flex-grow scrollbar-hide select-none relative'>
<div className={`bg-gradient-to-b ${color} to-black`}>
<section
className={`flex flex-col md:flex-row items-center justify-center p-4`}>
{props.children}
</section>
</div>
</div>
) : (
<p className='text-2xl'>Loading..</p>
)}
</Fragment>
)
}
But when I replace the color variable with a color value (say 'from-red-500') then the background color is visible in the rendered page.
I have also tried to replace the setColor code in useEffect with getStaticProps but the static version of the code cannot solve this problem (when color varible is used).
Thanks for any help.
This is a known issue with tailwindcss and dynamic classes, because the class is applied after rendering so its effect won't be generated by tailwind unless there was another element in that had the same class as a static class.
So, you can use tailwind "safelist" to resolve this.
In your tailwind.config, define a safelist array of all tailwind classes that you need to be generated and that don't exist in your code as static classes.
tailwind.config.js:
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
safelist: [
'from-red-500',
'from-orange-500',
'from-yellow-500',
'from-green-500',
'from-cyan-500',
'from-blue-500',
'from-indigo-500',
'from-violet-500',
'from-purple-500',
'from-pink-500',
]
// ...
}
Now this classes will always get generated so when you apply them dynamically, they will change accordingly.
Note that you need to restart your server after adding to the safelist.
Source
Another manual solution is to make a hidden element and add all your needed classes to it so they will be generated even if you get them dynamically after render
<div className="hidden from-red-500"></div>
but safelist is better I think
Using NextJS router my website is receiving the same image.
// user/[id]
const router = useRouter();
const { id } = router.query as {
id: string;
};
return (
<div>
<p>{id}</p>
<img src={...}/>
</div>
)
On page user/1 the image is correct. Clicking a button on page to user/2 displays the correct image for 2. When clicking back on the browser or window.history.back() to user/1 the image is still of user 2.
How do I do a complete refresh on the page to ensure the cache isn't used?
Setting a unique key for the img tag based on the page id will solve it.
<img key={id} src={...}/>
I am having a hard time figuring how to switch images inside react. I need the image to switch when I hover over a certain area. The area detection was created by someone else but I am been able to place my first image as the default. But I need to figure out how to change the image when I hover over the area.
This is what the images are imported as
import suitcase_open from '../images/suitcase_openEMPTY.png';
import box_open from '../images/discardbox_open.png';
import suitcase_closed from '../images/suitcase_closed.png';
import box_closed from '../images/discardbox_closed.png';
These are the two divs where I need to change the image
<div className='bound bound0'>
<img
id = 'box'
src = {box_closed}
/>
</div>
<span id='discard'>discard</span>
<div className='bound bound1' >
<img id = 'suitcase' src = {suitcase_closed} />
</div>
<span id='keep'>keep</span>
I was thinking about using onMouseOver but I do not know how to implement the change for the image source. I need to change from the closed to open versions.
You will likely need some state to track whether the suitcase is open or closed. You can then use a ternary operator to display the right image. The following code assumes you might also want to set it back to closed when mousing out.
function App() {
const [open, setOpen] = useState(false);
return (
<img
id='suitcase'
src={open ? suitcase_open : suitcase_closed}
onMouseOver={() => setOpen(true)}
onMouseOut={() => setOpen(false)}
/>
)
}
I want to display an image from a URL in React. For example, I want this image in tsx file
http://d1cs08zudd3ykv.cloudfront.net/dev/img/arrow-up.svg
to be displayed in reactJS. When I am trying to use requires not working but require is working with the local path. Is it possible to do or Is there any other way to do it? And how to do it?
Just set image src to URL of the image
const Component = (props) => {
return (
<div>
<img src="http://d1cs08zudd3ykv.cloudfront.net/dev/img/arrow-up.svg" alt="" />
</div>
);
};
I want to import image from other component but Why it's not show. in
Data.js I'm showing the image path. but when I want it . it's not show
in HOME. but Without Image Everything is work properly
Data.js
export const HomeObject = {
id: 'about',
img: require('../../Images/sv-1.svg'),
alt:'CAR',
}
Home.jsx
const Info = ({img, alt}) => {
return (
<Img src={img} alt={alt} />
)
React img works similar to html img tag. pass file path as src value to show the image.
when passing image src as prop to the component, keep in mind that it needs to be a string value. not require('...') value.
const Parent = () => {
return (<Info img={'../../Images/sv-1.svg'} alt={'info image'}>
};
const Info = ({img, alt}) => {
return (
<Img src={img} alt={alt} />
);
}
this works fine in local setup. but, when you deploy the application, serve the image as static resource and use it.