React - dynamic background image - javascript

Im new to React.
Im building and app where one of my components need to have a dynamic background image.
i have the menu-item component where it gets 2 props one of them is imgName which hold the the name like shoes.jpg.
for some reason i cant get it to be the background image.
here some of the code i have wrote
main-menu component
import React from 'react';
import MenuItem from '../menu-item/menu-item.component'
import './main-menu.style.scss'
class MainMenu extends React.Component {
constructor() {
super()
this.state = {
sections: [{
title: 'pants',
imgName: 'pants.jpg',
id: 1
},
{
title: 'shirts',
imgName: 'shirts.jpg',
id: 2
},
{
title: 'hats',
imgName: 'hats.jpg',
id: 14
},
{
title: 'jackets',
imgName: 'jackets.jpg',
id: 12
},
{
title: 'shoes',
imgName: 'shoes.jpg',
id: 6
}
]
}
}
render() {
return (
<div className="main-menu">
{this.state.sections.map(({ title, id, imgName }) => {
return (
<MenuItem imgName={imgName} title={title} key={id} />
)
})}
</div>
)
}
}
export default MainMenu
menu-item component
import React from 'react';
import './menu-item.styles.scss'
const MenuItem = ({ title,imgName }) => (
<div style={{backgroundImage:`url(../../../public/assets//'${imgName}')`}} className="menu-item">
<div className="content">
<h1 className="title">{title}</h1>
<span>buy now</span>
</div>
</div>
)
export default MenuItem;

You can try it:
<div style={{backgroundImage:`url(require(../../../public/assets//'${imgName}'))`}} className="menu-item">
<div className="content">
<h1 className="title">{title}</h1>
<span>buy now</span>
</div>
</div>

Related

React JS: How to add multiple placeholder object inside components

Sorry this question might be duplicated, but none of the existing answers helped me
I'm a beginner in React and js
I want to add multiple objects inside the component
Like:
src={url}
name={text}
subTitle={subtext}
my index.js
const tableColumns = [
{
title: 'Title/Artist',
dataIndex: 'name',
key: 'name',
render: (text) => (
<div className="d-flex align-items-center">
<AvatarStatus
shape="square"
src="https://i.scdn.co/image/ab67616d00001e02bd26ede1ae69327010d49946"
name={text}
subTitle="Dua Lipa"
/>
</div>
),
},
];
return (
<>
<Table
className="no-border-last"
columns={tableColumns}
dataSource={recentReleasesData}
rowKey='id'
pagination={false}
/>
</>
my data.js
export const RecentReleasesData = [
{
id: '#5332',
artwork: 'https://i.scdn.co/image/ab67616d00001e02bd26ede1ae69327010d49946',
name: 'Future Nostalgia',
artist: 'Dua Lipa',
label: 'Warner Records',
barcode: '19029500',
releasedate: '2021-02-11',
tracks: '11',
promolink: 'Smart Link',
status: 'Approved',
},
{
id: '#6438',
artwork: 'https://i.scdn.co/image/ab67616d00001e02caf82abb2338880577e472be',
name: 'Love',
artist: 'Someonw',
label: 'UMG Records',
barcode: '50029500',
releasedate: '2017-08-21',
tracks: '2',
promolink: 'Smart Link',
status: 'Rejected',
},
];
My comp AvatarStatus.js
import React from 'react';
import PropTypes from 'prop-types'
import { Avatar } from 'antd';
const renderAvatar = props => {
return <Avatar {...props} className={`ant-avatar-${props.type}`}>{props.text}
</Avatar>;
}
export const AvatarStatus = props => {
const { name, suffix, subTitle, id, type, src, icon, size, shape, gap, text,
onNameClick } = props
return (
<div className="avatar-status d-flex align-items-center">
{renderAvatar({icon, src, type, size, shape, gap, text })}
<div className="ml-2">
<div>
{
onNameClick ?
<div
onClick={() => onNameClick({name, subTitle, src, id})}
className="avatar-status-name clickable">{name}
</div>
:
<div className="avatar-status-name"><a href="javascript:void(0)">
{name}</a>
</div>
}
<span>{suffix}</span>
</div>
<div className="text-muted avatar-status-subtitle">{subTitle}</div>
</div>
</div>
)
}
AvatarStatus.propTypes = {
name: PropTypes.string,
src: PropTypes.string,
type: PropTypes.string,
onNameClick: PropTypes.func
}
export default AvatarStatus;
https://reactjs.org/docs/components-and-props.html
components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.
This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “function components” because they are literally JavaScript functions.
codepen example
I found the solution
index.js
render: (_, record) => (
<Flex>
<AvatarStatus
shape="square"
size={50}
src={record.artwork}
name={record.title}
subTitle={record.artist}/>
</Flex>
),

React: mapping through a list of svg images

I am trying to map through a list of svg images and show enough description corresponding to the svg image.
index.js
import {ReactComponent as Pic1} from "../../../../assets/buyer-1.svg";
import {ReactComponent as Pic2} from "../../../../assets/buyer-2.svg";
import {ReactComponent as Pic3} from "../../../../assets/buyer-3.svg";
const data = [
{
id: `1`,
title: "Coming soon",
description:'',
img: Pic1,
},
{
id: `2`,
title: "Coming soon",
description:'',
img: Pic2,
},
{
id: `3`,
tile: "Coming soon",
description:'',
img: Pic3,
},
]
function Test() {
return (
{data.map(({ id, title,description, img }) => (
<div key={id} className="guest--item swiper-slide">
<div>
<img key={id} src={img} alt='mySvgImage' />
<h1>{title}</h1>
<h2>{description}</h2>
</div>
</div>
))}
)}
currently when i check my react website i can only see mySvgImage which is the alt 3 times and cant see the actual image
You are importing SVG's as React Component hence you should use them as Component itself.
In you code you are passing a React Component (SVG's which you imported as React Component) as a src attribute to an <img> tag which is invalid.
import React from "react";
import ReactDOM from "react-dom";
import {ReactComponent as Pic1} from "../../../../assets/buyer-1.svg";
import {ReactComponent as Pic2} from "../../../../assets/buyer-2.svg";
import {ReactComponent as Pic3} from "../../../../assets/buyer-3.svg";
const data = [
{
id: `1`,
title: "Coming soon",
description: "",
Image: Pic1
},
{
id: `2`,
title: "Coming soon",
description: "",
Image: Pic2
},
{
id: `3`,
tile: "Coming soon",
description: "",
Image: Pic3
}
];
function Test() {
return (
<>
{data.map(({ id, title, description, Image }) => (
<div key={id}>
<div>
<Image /> {/* Use Image as Component */}
<h1>{title}</h1>
<h2>{description}</h2>
</div>
</div>
))}
</>
);
}
Because you are importing your images the wrong way. I have made this working CodeSandbox which is exactly the same as your example. Check how I imported images and it's working just fine. CodeSandbox
Where you got it wrong is importing SVG as React Component and using for a src attribute in an img tag.
So u don't need to import as ReactComponent.
You can import this way.
import Pic1 from "../../../../assets/buyer-1.svg";
import Pic1 from "../../../../assets/buyer-1.svg";
import Pic2 from "../../../../assets/buyer-2.svg";
import Pic3 from "../../../../assets/buyer-3.svg";
const data = [
{
id: `1`,
title: "Coming soon",
description:'',
img: Pic1,
},
{
id: `2`,
title: "Coming soon",
description:'',
img: Pic2,
},
{
id: `3`,
tile: "Coming soon",
description:'',
img: Pic3,
},
]
function Test() {
return (
{data.map(({ id, title,description, img }) => (
<div key={id} className="guest--item swiper-slide">
<div>
<img key={id} src={img} alt='mySvgImage' />
<h1>{title}</h1>
<h2>{description}</h2>
</div>
</div>
))}
)}

Why I can't scroll a div into view?

So I have a sidebar, and when I click on one of the items, it should scroll to div with a certain name. It worked before, but I decided to add 'active' class to the item clicked to change its color, and it stopped scrolling to divs.
Sidebar.jsx file:
import React, { useState} from 'react';
import './Sidebar.scss';
import { SlidebarData } from "./SlidebarData";
import spike from '../../assets/spike_pic.jpg';
const Sidebar = () => {
const [sideBar, setSidebar] = useState(false);
const [selectedLink, setSelectedLink] = useState("");
return (
<div className="sidebar">
<span className="btn" onClick={() => setSidebar(!sideBar)}>Menu</span>
<div className="profile">
<img src={spike}/>
<span>Alim Budaev</span>
<span>Available for work</span>
</div>
<ul className="sidebarlist" id={sideBar ? "hidden" : ""}>
{SlidebarData.map((val,key) =>{
return (
<li
className={`row ${selectedLink === val.link ? "active" : ""}`}
id={val.link}
key={key}
onClick={()=> {
setSelectedLink(val.link);
document.getElementById(val.link).scrollIntoView();
}}>
{""}
<div>
{val.title}
</div>
</li>
);
})}
</ul>
</div>
);
}
export default Sidebar;
As you see, I have a setState hook for selectedlink, which adds active class, but scrollIntoView doesn't work because of it, and I can't figure out why.
SidebarData.jsx, where I get links from:
export const SlidebarData = [
{
title: "Home",
link: "home"
},
{
title: "About",
link: "about"
},
{
title: "Services",
link: "services"
},
{
title: "Contact",
link: "contact"
}
]

Trying to turn an array into a list

I have a problem with my function that turns data from an array into a list in different component.
I think the problem is with my lack of understanding where to put document.GetElementById().
I get error document.getElementById(...) is null.
Is it because I try to access specific location before it is rendered? Then how should I access it, maybe it has something to do with component lifecycle? Here is my code:
import React, { Component } from 'react';
import Day from "./day";
import image1 from "./img/eggs.jpg";
class Stuff extends Component {
constructor(props){
super(props);
this.makeList = this.makeList.bind(this);
}
makeList(array) {
var list = document.createElement('ul');
for (var i = 0; i < array.length; i++) {
var item = document.createElement('li');
item.appendChild(document.createTextNode(array[i]));
list.appendChild(item);
}
return list;
}
render() {
const source = {
breakfast: [
{
id: 1,
name: "eggs",
img: image1,
description: "Start a day with delicious and nutricious eggs!",
ingridients: ['2 eggs', 'two slices of toast', 'bacon', 'butter']
},
...
]}
return (
<div>
<Day {...source}
makeList={this.makeList} />
</div>
);
}
}
export default Stuff;
and Day component where React turn an error:
import React, { Component } from 'react';
import "./day.css";
class Day extends Component {
render() {
const appChild = document.getElementById('foo').appendChild(this.props.makeList(this.props.source.breakfast.ingridients));
return (
<div className="displayOne">
<img src= {this.props.breakfast[0].img} alt="eggs" />
<h3>{this.props.breakfast[0].description}</h3>
<div id="foo">
<p>{appChild}</p>
</div>
</div>
);
}
}
export default Day;
Thank you for help and understanding!
you probably should use jsx instead of manipulating the dom directly:
function makeList(array) {
return (
<ul>
(array.map((value, index) => (<li>{value}</li>)
</ul>
)
}
or a full, more optimal, solution would be to create a Breakfast component:
class Stuff extends Component {
constructor(props) {
super(props);
this.source = {
breakfast: [
{
id: 1,
name: "eggs",
img: image1,
description: "Start a day with delicious and nutricious eggs!",
ingridients: ['2 eggs', 'two slices of toast', 'bacon', 'butter']
},
]
}
}
render() {
return (
<div>
<Day source={this.source}></Day>
</div>
);
}
}
class Day extends Component {
render() {
return (
<div className="displayOne">
{this.props.source.breakfast.map((breakfast) => <Breakfast breakfast={breakfast}/>)}
</div>
);
}
}
function Breakfast({breakfast}) {
return (
<div className="displayOne">
<img src={breakfast.img} alt="eggs"/>
<h3>{breakfast.description}</h3>
<ul>
{breakfast.ingridients.map((ingridient) => <li>{ingridient}</li>)}
</ul>
</div>
)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
In generall, if you haven't done already. I would advice you to go through the "Getting Started" guide of React to understand the "way of react".
Here is the official "Intro to React": https://reactjs.org/tutorial/tutorial.html

Why can't I declare a function before render in React?

So my code works, but if I move handleClick() to the render, It will throw an error. Same if I try to declare a function like
var handleClick = () => {
this.setState({reservationVisible: true})
console.log(this.state.reservationVisible)}
outside render.
Also when I'm passing handleClick() as a prop, I need to call {this.handleClick.bind(this)} and when I'm using a function, declared inside render, {handleClick.bind(this) is enough. I don't really understand why. Where should I declare functions then? Outside or inside render? Should I use functions or methods?
Here is my code:
import React, { Component } from 'react';
import Room from './Room'
import Form from './Form'
class Rooms extends Component {
constructor(props){
super(props);
this.state = {reservationVisible: false}
}
handleClick(e){
this.setState({reservationVisible: true})
console.log(this.state.reservationVisible)
}
render(){
let rooms = [
{
roomNumber: '1',
type: 'Cool room',
price: '130 $',
goods: ['radio', 'phone']
},
{
roomNumber: '2',
type: 'Cozy Room ',
price: '165 $',
goods: ['radio', 'phone, tv']
},
{
roomNumber: '3',
type: 'Dirty Room',
price: '130 $',
goods: ['balcony', 'phone']
},
{
roomNumber: '4',
type: 'Like Real Dirty Room',
price: '90 $',
goods: ['fridge', 'phone', 'balcony']
}
]
let getElements = (room, i) => {
return(
<Room
key={i}
roomNumber={room.roomNumber}
type={room.type}
price={room.price}
goods={room.goods.map(good => good + ", ")}
onClick={this.handleClick.bind(this)}
/>
)
};
let roomsMapped = rooms.map(getElements);
return(
<div>
{roomsMapped}
</div>
)
}
}
export default Rooms
and the Room component
import React, { Component } from 'react';
class Room extends Component{
render(){
return (
<div className="room">
<div className="image"><h1>Image nr {this.props.roomNumber}</h1></div>
<div className="buttonGroup">
<div className="button galleryButton">Gallery</div>
<div className="button reserve" onClick={this.props.onClick.bind(this)}> I'll take it</div>
</div>
<div className="info">
<div className="topInfo">
<span className="left">{this.props.type}</span>
<span className="right">{this.props.price}</span>
</div>
<div className="additional">
{this.props.goods}
</div>
</div>
</div>
)
}
}
export default Room

Categories

Resources