I'm looping through products by mapping them and the justify-content-around doesn't apply to them and I'm using bootstrap 4 in my react project .
Here is my code :
{props.products.map((item) => {
if (item.inCart) {
return (
<div className="d-flex justify-content-around w-100" key={item.id}>
<button>remove</button>
<div>
<h5>{item.name}</h5>
</div>
<div>
<h5>{item.price.toLocaleString('ar-EG')}</h5>
</div>
<div>
<h5>{item.number.toLocaleString('ar-EG')}</h5>
</div>
<div>
<h5>{(item.number * item.price).toLocaleString('ar-EG')}</h5>
</div>
<hr />
</div>
);
}
The display flex class applies but not the other one and they all have no margin between them .
How can I make them to display justify-content-around ??
Your problem come from the <hr> tag. I just discovered it by doing this repro on stackblitz. Remove it and it works.
If you readlly need it then just receate it:
const Divider = () => {
return <div className="border-bottom" />;
};
This one is bootstrap dependant but of course you can make it generic easily. You just need to apply it outside of your flex container :
<>
<div className='d-flex justify-content-around' key={item.id}>
<button>remove</button>
<h5>{item.name}</h5>
<h5>{item.name}</h5>
<h5>{item.name}</h5>
</div>
<Divider />
</>;
Related
I use to Map method to display data form API but data is not aligned properly I apply reverse method to reverse data but reverse is not working properly
I create this function to display data:
const blogCategory = (item) => {
return(
<>
<div>
<div key={item.title} className="mx-3" style=
{{display:"flex",justifyContent:"center",height:"750px"}}>
<div className="blog bolg-post">
<div className="img-hover-zoom">
<Link href={`/blogs/${item.title.replace(urlR,"-").replace('?',"")}`}>
<img style={{cursor:"pointer"}} className="blog-box" src={item.urlToImage}/>
</Link>
</div>
<div className="d-flex flex-column">
<span className="name-blog">{item.category}</span>
<Link href={`/blogs/${item.title.replace(urlR,"-").replace('?',"")}`}>
<span style={{cursor: "pointer",textAlign:"justify",maxHeight:"62px",overflow:"hidden"}} className="heading-blog">{item.title}</span>
</Link>
<div style={{height:"100px",overflow:"hidden",textAlign:"justify"}} className="para-blog">{item.meta_description}</div>
{/* <div style={{height:"100px",overflow:"hidden",textAlign:"justify"}} className="para-blog" dangerouslySetInnerHTML={{ __html: item.content }}/> */}
<Link href={`/blogs/${item.title.replace(urlR,"-").replace('?',"")}`}>
<button className="btn-blog mt-3">{item.readingTime} min read</button>
</Link>
</div>
</div>
</div>
</div>
</>
)
}
I use Map method to display data by using this function as show in below:
<div className='d-flex col-12' style={{width:"1000px"}}>
<div style={{height:"650px",overflow:'hidden'}}>
{cat.filter(categ=>categ.category === 'technology').reverse().map(
blogCategory
)}
</div>
<div className="products">
{cat.filter(categ=>categ.category === 'technology').map(
productCategory
)}
</div>
</div>
Data is displaying properly but does not align like [0,1,2,3,4,5,6,7,8,9] it displays like [9,8,7,6,5,4,3,2,1,0] .
This is where Tab header and tab content is defined, expectation is Tabs_content has component name, and under tabpanel it should traverse array tabs_content and display component < AddQueueCard /> and call the component shown in image 3
let tabs_data= ['Add Queue','Edit Queue','Remove Queue'];
let tabs_content= ['<AddQueueCard />','EditQueueCard','C content' ];
<div class="card-body">
<div class="tab-content">
<div class="tab-pane active">
<div>
<div id="test">
<Tabs>
<ul>
<TabList>
{tabs_data.map(i => (
<Tab>{i}</Tab>
))}`***enter code here***`
</TabList>
</ul>
{tabs_content.map(i => (
<TabPanel>
{i} {/* here I want to call cards dynamically like <AddQueueCard /> <EditQueueCard> if clicked on 1st or 2nd tab respectively. How do I do that */}
</TabPanel>
))}
</Tabs>
</div>
</div>
</div>
<div class="tab-pane">
</div>
</div>
</div>
Just pass Component itself , but its better to have a separate component dictionary and loop through that for rendering dynamic component, don't mix component and other things in one array, if you did you have to find a way to detect that item is react component and then render it.
let tabs_data= ['Add Queue','Edit Queue','Remove Queue'];
let tabs_content= [AddQueueCard, EditQueueCard, 'C content'];
<div class="card-body">
<div class="tab-content">
<div class="tab-pane active">
<div>
<div id="test">
<Tabs>
<ul>
<TabList>
{tabs_data.map((i) => (
<Tab>{i}</Tab>
))}
</TabList>
</ul>
{tabs_content.map((Item) => {
return <TabPanel>
{typeof Item === "function" ? <Item /> : Item}
</TabPanel>
})}
</Tabs>
</div>
</div>
</div>
<div class="tab-pane"></div>
</div>
</div>;
I want to do getElementById to give css effect and click to slide function.
how do I use DOM in react? Thank you in advance.
function Auth() {
//this part needs to be fixed
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('body');
signUpButton.addEventListener('click', () =>
container.classList.add('right-panel-active'));
signInButton.addEventListener('click', () =>
container.classList.remove('right-panel-active'));
Here are the classnames that might help you understand my code better.
return (
<div className ="auth">
<div className="body" id="body">
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button className="slide__btn" id='signUp' > Sign In </button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button className="slide__btn" id='signIn' > Sign Up </button>
</div>
</div>
</div>
</div>
</div>
)
}
I guess the propose to use React is that fact you should interact in the component state.
I suggest you use State in your component and add some according to some interaction
function App() {
const [mode, setMode] = React.useState();
const handleMode = (mode) => {
setMode(mode);
};
const containerClasses =
mode === "signUp" ? "body right-panel-active" : "body";
return (
<div className="auth">
<div className={containerClasses} id="body">
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button
className="slide__btn"
id="signUp"
onClick={() => handleMode("signIn")}
>
{" "}
Sign In{" "}
</button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button
className="slide__btn"
id="signIn"
onClick={() => handleMode("signUp")}
>
{" "}
Sign Up{" "}
</button>
</div>
</div>
</div>
</div>
</div>
);
}
You should avoid direct modification of the dom in React. React assumes that it is the only piece of code modifying the dom, and so it won't know about any changes you make. This opens up the possibility of bugs where react changes something on the dom that you don't expect, or doesn't change something you do expect. A simple piece of code like yours won't have these bugs, but best to learn the react way now so you don't run into these issues with more complicated code.
The react way to do this is to pass onClick props to the elements that need it, and to have a state variable which controls the class names. For example:
import React, { useState } from 'react';
function Auth() {
const [showPanel, setShowPanel] = useState(false);
return (
<div className="auth">
<div className={showPanel ? "body right-panel-active" : "body"}>
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button
className="slide__btn"
onClick={() => setShowPanel(false)}
>
Sign In
</button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button
className="slide__btn"
onClick={() => setShowPanel(true)}
>
Sign Up
</button>
</div>
</div>
</div>
</div>
</div>
);
}
Heres my question, if I update a state item which has been set to an Array item (array[0]) to another item in that Array (array[1]) and I've got other state items that are referencing that array, should react know that the other state items need to be updated?
If yes then why does my test below not work:
Class Decking extends React.Component {
constructor(props) {
super(props)
this.state = {
firstOption: props.product.acf.options.product_option[0],
title: props.product.title,
}
this.state.product = {
mainImage: {
url: this.state.firstOption.image_gallery[0].source_url,
alt: this.state.firstOption.image_gallery[0].alt_text,
},
thumbnails: this.state.firstOption.image_gallery,
price: this.state.firstOption.price,
dimensions: this.state.firstOption.dimensions,
options: props.product.acf.options.product_option,
desc: this.state.firstOption.description,
spec: this.state.firstOption.size___length_spec
}
}
toggleOptions(id) {
const option = this.state.product.options[id]
this.setState({firstOption: option})
}
render() {
return (
<div>
<div className="flex flex-wrap">
<div className="w-1/2">
<img className="w-full shadow-xl" alt={this.state.product.mainImage.alt} src={this.state.product.mainImage.url} />
<div className="-ml-2">
{this.state.product.thumbnails.map((thumbnail, index) => (
<img className="w-16 border-solid border-3 border-blue-400 mx-2" key={index} src={thumbnail.source_url} alt={thumbnail.alt_text} />
))}
</div>
</div>
<div className="w-1/2 pl-8">
<h1 className="text-4xl leading-normal">{this.state.title}</h1>
<div className="flex flex-wrap justify-between text-2xl mb-6">
<div className="font-light">
{this.state.product.dimensions}
</div>
<div className="font-light">
<b>Price:</b> {this.state.product.price}
</div>
</div>
<span className="text-xl font-light mb-4 block">Avaliable Options:</span>
<div className="flex flex-wrap mb-6 lg:mb-0">
{this.state.product.options.map((option, i) => (
<div className="w-full border-solid border-1 border-blue-400 shadow-lg flex items-center mb-4 px-5 py-4" key={i}>
<input onChange={e=>this.toggleOptions(e.target.id)} id={i} type="radio" /> <p className="checkChange mb-0 pl-4">{option.profileoption}</p>
</div>
))}
</div>
<div className="w-full nomargin mb-4">
<b className="text-xl">Desc:</b>
<div dangerouslySetInnerHTML={{__html: this.state.product.desc}} />
</div>
<div className="w-full nomargin">
<b className="text-xl">Spec:</b>
<div dangerouslySetInnerHTML={{__html: this.state.product.spec}} />
</div>
</div>
</div>
</div>
)
}
}
I've set this.state.firstOption to an array item props.product.acf.options.product_option[0]
That item changes when my toggleOptions method gets called :
toggleOptions(id) {
const option = this.state.product.options[id]
this.setState({firstOption: option})
}
And here is where the the method is called:
<div>
{this.state.product.options.map((option, i) => (
<div key={i}>
<input onChange={e=>this.toggleOptions(e.target.id)} id={i} type="radio" /> <p>{option.profileoption}</p>
</div>
))}
</div>
I hope I've made my question clear, I appreciate your attention :)
Within toggleOptions this will be undefined. To solve this you can bind the event handler in the constructor like this:
constructor( props ){
super( props );
this.toggleOptions = this.toggleOptions.bind(this);
}
Or you could define toggleOptions as an arrow function like so:
const toggleOptions = (id) => {
const option = this.state.product.options[id];
this.setState({firstOption: option});
}
Using an arrow function automatically binds the scope of this to the function.
I am using a function that maps every item in the props array to creating an image tag. I am trying to make every 3 images have a row div around them using bootstrap so they will fit the page correctly, but I cannot figure out how to do it. Any help would be appreciated. Here is the code:
import React, { Component } from 'react';
import "./Skills.css";
export default class Skills extends Component {
static defaultProps = {
images: [
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/HTML5_logo_and_wordmark.svg/1200px-HTML5_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/CSS3_logo_and_wordmark.svg/1200px-CSS3_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png",
"https://p7.hiclipart.com/preview/306/37/167/node-js-javascript-web-application-express-js-computer-software-others.jpg",
"https://bs-uploads.toptal.io/blackfish-uploads/skill_page/content/logo_file/logo/5982/express_js-161052138fa79136c0474521906b55e2.png",
"https://webassets.mongodb.com/_com_assets/cms/mongodb_logo1-76twgcu2dm.png",
"https://www.pngfind.com/pngs/m/430-4309307_react-js-transparent-logo-hd-png-download.png",
"https://botw-pd.s3.amazonaws.com/styles/logo-thumbnail/s3/012015/bootstrap.png?itok=GTbtFeUj",
"https://sass-lang.com/assets/img/styleguide/color-1c4aab2b.png"
]
}
photo() {
return (
<div >
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
);
}
render() {
return (
<div id="skills-background" className="mt-5">
<div id="skills-heading" className="text-center">Skills I've Learned:</div>
<div className="container">
<div className="row">
{this.photo()}
</div>
</div>
</div>
)
}
}
CodeSandbox
I think, I found the issue,
<div> <-----This div is the issue
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
You have wrapped your col-md-4 with a div, and div has display: block style, so you are getting every image on separate row. Simply replace div with Fragments,
<> <-----Make it Fragment
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</>