How can I target a specific div with onClick? - reactjs

I'm building a NetFlix clone main page.
I have already the list of movies,tv series ecc.. rendered horizontal.
I'd like to click on the next arrow and slide only the relative section.
Now if I click the next arrow on the first section, the second one above scroll and I don't want that..
How can I achieve it?
I tried to google it and some tutorials but I can't find how to target elements in the same parent with onClick.
Thank you very much
class App extends React.Component {
state = { moviesNow: [], tvSeries: [], actionMovies: [], animation: [] };
containerSection = React.createRef();
handleClick = e => {
this.containerSection.current.style.transform = `translateX(-100%)`;
};
render() {
return (
<div className="container">
<h1 className="section-title">Now playing</h1>
<div className="wrapper">
<div className="nextArrow" onClick={this.handleClick}>
<img src={nextArrow} alt="" />
</div>
<div ref={this.containerSection} className="container-section">
<MovieItem movies={this.state.moviesNow} />
</div>
</div>
<h1 className="section-title">TV Series</h1>
<div className="wrapper">
<div className="nextArrow" onClick={this.handleClick}>
<img src={nextArrow} alt="" />
</div>
<div ref={this.containerSection} className="container-section">
<MovieItem movies={this.state.tvSeries} />
</div>
</div>

You are using only one ref for two different elements, I guess that is where you issue is coming from. So I updated handleClick to be able to receive a ref as an argument and return a function that will receive the event :
handleClick = ref => e => {
ref.current.style.transform = `translateX(-100%)`;
};
Then you can use handleClick this way:
<div className="nextArrow" onClick={this.handleClick(secondContainerSection)}>
<img src={nextArrow} alt="" />
</div>
Eventually it gives you something like this:
class App extends React.Component {
state = { moviesNow: [], tvSeries: [], actionMovies: [], animation: [] };
containerSection = React.createRef();
//a new ref
secondContainerSection = React.createRef();
handleClick = ref => e => {
ref.current.style.transform = `translateX(-100%)`;
};
render() {
return (
<div className="container">
<h1 className="section-title">Now playing</h1>
<div className="wrapper">
<div className="nextArrow" onClick={this.handleClick(containerSection)}>
<img src={nextArrow} alt="" />
</div>
<div ref={this.containerSection} className="container-section">
<MovieItem movies={this.state.moviesNow} />
</div>
</div>
<h1 className="section-title">TV Series</h1>
<div className="wrapper">
<div className="nextArrow" onClick={this.handleClick(secondContainerSection)}>
<img src={nextArrow} alt="" />
</div>
<div ref={this.secondContainerSection} className="container-section">
<MovieItem movies={this.state.tvSeries} />
</div>
</div>

make a seperate component for drawer and define the ref inside it
drawer Component
class Drawer extends React.Component {
containerSection =new React.createRef();
handleClick = e => {
this.containerSection.current.style.transform = `translateX(-100%)`;
};
render() {
return (
<div className="wrapper">
<div className="nextArrow" onClick={this.handleClick}>
<img src={nextArrow} alt="" />
</div>
<div ref={this.containerSection} className="container-section">
{this.props.children}
</div>
</div>
Main component
class App extends React.Component {
state = { moviesNow: [], tvSeries: [], actionMovies: [], animation: [] };
containerSection = React.createRef();
handleClick = e => {
this.containerSection.current.style.transform = `translateX(-100%)`;
};
render() {
return (
<div className="container">
<h1 className="section-title">Now playing</h1>
<Drawer><MovieItem movies={this.state.moviesNow} /></Drawer>
<h1 className="section-title">TV Series</h1>
<Drawer><MovieItem movies={this.state.tvSeries} /></Drawer>
</div>);

Related

How to add different events with this Class |REACT JS|

I wrote down the code below.
My outcome should be 4 buttons that increment and decrement a value.
Is working but all buttons change at the same time!
The outcome I would like to get button by button and not at the same time.
I've already tried with an Array but seems I'm not on the right way!
import React from 'react';
class Counter extends React.Component {
constructor() {
super();
this.state = {
cnt: 0
};
}
handleDecrement = () => {
this.setState({
cnt: this.state.cnt + 1
});
}
handleIncrement = () => {
this.setState({
cnt: this.state.cnt - 1
});
}
render() {
return (
<><div className = "btn"></div>
<header>
<h1>Tarantino Shop</h1>
</header>
<div>
<img src= "images/walltara.png" alt="cart" width = "80%"/>
</div>
<div className="divprimario">
<div className="items">
<img src= "images/tara1.jpg" alt="cart" />
<div className = "titles"> T-Shirt Pulp Fiction</div>
<div>
<button onClick={this.handleDecrement}>+</button>
<p>{this.state.cnt} </p>
<button onClick={this.handleIncrement}>-</button>
</div>
</div>
<div className="items">
<img src= "images/tara2.jpg" alt="cart" />
<div className = "titles">T-Shirt Tarantino </div>
<div>
<button onClick={this.handleDecrement}>+</button>
<p>{this.state.cnt} </p>
<button onClick={this.handleIncrement}>-</button>
</div>
</div>
<div className="items">
<img src= "images/tara3.jpg" alt="cart" />
<div className = "titles">T-Shirt Le Iene</div>
<div>
<button onClick={this.handleDecrement}>+</button>
<p>{this.state.cnt} </p>
<button onClick={this.handleIncrement}>-</button>
</div>
</div>
<div className="items">
<img src= "images/tara4.jpg" alt="cart" />
<div className = "titles">T-Shirt Random</div>
<div>
<button onClick={this.handleDecrement}>+</button>
<p>{this.state.cnt} </p>
<button onClick={this.handleIncrement}>-</button>
</div>
</div>
</div>
</>
);
}
}
export default Counter;
So, why all the buttons change at the same time? What am I'm doing wrong?
you are only using one variable cnt to keep track of the count. If you want them to update separately, each button must increment or decrement a different state variable.
For example you could use pulpFictionCnt, tarantinoCnt etc to keep track of the different counts.
Keep a separate component for your Counter and provide other data as props.
import React from "react";
class Counter extends React.Component {
constructor() {
super();
this.state = {
cnt: 0
};
}
handleDecrement = () => {
this.setState({
cnt: this.state.cnt + 1
});
};
handleIncrement = () => {
this.setState({
cnt: this.state.cnt - 1
});
};
render() {
return (
<>
<div className="divprimario">
<div className="items">
<img src="images/tara1.jpg" alt="cart" />
<div className="titles">{this.props.title}</div>
<div>
<button onClick={this.handleDecrement}>+</button>
<p>{this.state.cnt} </p>
<button onClick={this.handleIncrement}>-</button>
</div>
</div>
</div>
</>
);
}
}
export default Counter;
Following may be some other component,
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import Counter from "./Counter";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<div>
<div className="btn"></div>
<header>
<h1>Tarantino Shop</h1>
</header>
<div>
<img src="images/walltara.png" alt="cart" width="80%" />
</div>
<Counter title={"T-Shirt Pulp Fiction"} />
<Counter title={"T-Shirt Tarantino"} />
<Counter title={"T-Shirt Le Iene"} />
<Counter title={"T-Shirt Random"} />
</div>
</StrictMode>,
rootElement
);
Sandbox code here => https://codesandbox.io/s/laughing-bhabha-zsyvw?file=/src/Counter.js

Get position of 3 seperate divs in ReactJS

I have 3 divs, which I'm displaying in a ReactJS app.
I'm displaying the divs, by looping through an object of classNames stored in state. (Each className has it's own CSS styling, which displays a color - hat1, hat2, hat3).
OnClick, I want to get the div coordinates/position of any of the 3 divs I click on.
I've tried using React.createRef() and getBoundingClientRect(). However, both methods give me the same coordinates, no matter which div I click on.
It looks like it's returning the coordinates of the <section> tag, rather than the target div element I click on...
What am I doing wrong?
class Cylinders extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = {
divs: [
{
className: 'hat1'
},
{
className: 'hat2'
},
{
className: 'hat3'
}
]
}
}
componentDidMount = () => {
console.log('mount');
}
handleClick = (item, i) => {
console.log('item', item);
console.log('i', i);
var divCoordinates = ReactDOM.findDOMNode(this).getBoundingClientRect();
console.log(divCoordinates, 'divCoordinates');
// const node = this.myRef.current;
// console.log('node', node);
}
render() {
return (
<section>
<div className="columns is-mobile">
<div className="column">
<h1 className="title has-text-black is-size-2">Cylinders Game</h1>
<button className="has-text-black">Ball container</button>
</div>
</div>
<div className="columns is-mobile">
<div className="colum ballContainer">
<div className="ball"></div>
</div>
</div>
<div className="columns is-mobile">
{this.state.divs.map((item, i) => {
return (
<div className="column">
<div className="columns is-multiline">
<div
onClick={() => this.handleClick(item, i)}
className={item.className}
key={item.name + i}
ref={el => this.containerLine = el}
> {i}
</div>
</div>
</div>
)
})}
</div>
</section>
);
}
}
export default Cylinders;
I got it working!
I simply targeted the item, with item.target.
var divCoordinates = ReactDOM.findDOMNode(item.target).getBoundingClientRect();

Render N times component based on the data in object

I am new at React. Will be glad if someone can help:
I have parent (Dashboard) which contains all data. This data is passed to the children component (OnBoardingCard).
How can I render n times the OnBoardingCard component based on the data in the object at Dashboard without using the [num](in this case 3 times - 3x OnBoarding Cards;)?
Thank you!!
Parent- Dashboard
const cardData = [
{
svg: icon1,
title: 'Add',
content: 'add more'},
{
svg: icon2,
title: 'remove',
content: 'remove'
},
{
svg: icon3,
title: 'move',
content: 'move down'
}];
class Dashboard extends Component {
render() {
return (
<Section>
<OnboardingCard listData={cardData}/>
</Section>
);
} }
Children- OnBoardingCard
import Dashboard from "../../../../screens/Dashboard/index.js";
class OnboardingCard extends Component {
render() {
return (
<div className={styles.cardHolder}>
<div className={styles.fullCard}>
<div className={styles.onboardingCard}>
<div className={styles.iconBackground}>
<img src={this.props.listData[0].svg} />
</div>
<div className={styles.title}>{this.props.listData[0].title}</div>
</div>
<p className={styles.cardDescription}>
{this.props.listData[0].content}
</p>
</div>
</div>
); }}
When you are using a map inside render assign a unique key to its child component.
render(){
return(
{this.props.listData.map((item, i) =>
<div className={styles.cardHolder} key={i}>
<div className={styles.fullCard}>
<div className={styles.onboardingCard}>
<div className={styles.iconBackground}>
<img src={this.props.listData[0].svg} />
</div>
<div className={styles.title}>{this.props.listData[0].title}</div>
</div>
<p className={styles.cardDescription}>
{this.props.listData[0].content}
</p>
</div>
</div>
)}
);
}
You can use map function,
like this,
{this.props.listData.map((item)=>
<div className={styles.cardHolder}>
<div className={styles.fullCard}>
<div className={styles.onboardingCard}>
<div className={styles.iconBackground}>
<img src={item.svg} />
</div>
<div className={styles.title}>{item.title}</div>
</div>
<p className={styles.cardDescription}>
{item.content}
</p>
</div>
</div>)}
<Section>
<div className={styles.cardRow}>
{cardData.map((card, i) => (
<OnboardingCard {...card} key={i} />
))}
</div>
</Section>
This is what I meant (and wanted to do). So this solves my question. Thanks everyone!!

Not able to get data in props in react js

Following is my code to retrieve data from firebase and view it in a bootstrap carousel. I can see the values in the console but I'm not able to get it in the props on another component.
class JobOfferSlider extends Component {
componentDidMount = () => {
var ref = fire.database().ref("Employers/Employer1");
ref.orderByKey().on("child_added", (snapshot) => {
this.setState({ slidercontents: snapshot.val()})
console.log(this.state.slidercontents);
console.log(this.state.slidercontents.Title)
});
var empref = fire.database().ref("Employers/");
empref.orderByKey().on("child_added", (snapshot) => {
this.setState({ employers: snapshot.key})
console.log(this.state.employers);
});
}
state ={
slidercontents : [], employers : []
}
and i use the props in the following jsx file
class Slidercontent extends Component {
componentWillUpdate = ()=>{
console.log(this.props.employers);
}
render() {
return (
<div className="col-sm text-center border rounded shadow p-3 m-3">
<div className="row">
<div className="col-md-3">
<div className="profilepic"></div>
</div>
<div className="col-md-9">
<h6 className="pt-2 float-left">{this.props.employers}</h6>
</div>
</div>
<h5 className="font-weight-bold pt-3 text-left">{this.props.slidercontents.Description}</h5>
<h5 className="font-weight-bold pt-3 text-left ">{this.props.slidercontents.RatePerHour}</h5>
<div className="row pt-3">
<div className="col-md-2">
<div><i class="fas fa-map-marker-alt"></i></div>
</div>
<div className="col-md-5">
<p className="float-left">{this.props.slidercontents}</p>
</div>
<div className="col-md-5">
<p className="float-right">5 mins ago</p>
</div>
</div>
</div>
);
}
}
But the props stays undefined.... any help on how to access the state values?
Pass the parent component's state as props to the child component (in the render function):
render() {
return <Slidercontent employers={this.state.employers}
}
This way, you can access the employers in the child component by:
{this.props.employers}

How to make one common H1 element for few sections in React

How to make one common H1 element for sections: Skills and About. If I clicked Skills Button H1 change to Skills and if i clicked About btn H1 change to About. I need this h1 element only for this two section and be oscillated by same value in css. For Start section it shouldn't be. Should I use state/props?
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Contact extends Component {
get show() {
return this.props.activeSection === "contact";
};
render() {
if(this.show) {
return (
<div className='contact'>
<h1>kontakt!</h1>
<a href='' target='_blank'>
<img src='' />
</a>
<a href={cvpdf} target='_blank'>
<img src='' />
</a>
<a href='' target='_blank'>
<img src='' />
</a>
<a className="mailto" href="">
<img src='' />
</a>
</div>
);
} else {
return null;
};
};
};
class Skills extends Component {
get show() {
return this.props.activeSection === "skills";
};
render() {
if (this.show) {
return (
<div className='intro skills'>
<h1>skills</h1>
<img src='' alt=''/>
<img src='' alt=''/>
<img src='' alt=''/>
<img src='' alt=''/>
<img src='' alt=''/>
<img src='' alt=''/>
<img src='' alt=''/>
<img src='' alt=''/>
</div>
);
} else {
return null;
};
};
};
class About extends Component {
get show() {
return this.props.activeSection === "about";
};
render() {
if (this.show) {
return (
<div className='intro about'>
<h1>about</h1>
<p>
Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content Content
</p>
</div>
);
} else {
return null;
};
};
};
class Start extends Component {
get show() {
return this.props.activeSection === "start";
};
render() {
if (this.show) {
return (
<div className='intro start'>
<h1>Name Surname</h1>
<p>Content Content Content Content Content Content </p>
<h2>Content Content Content Content Content Content Content Content </h2>
</div>
);
} else {
return null;
};
};
};
const Main = ({ activeSection }) => (
<React.Fragment>
<div className="container border">
<Start activeSection={activeSection}/>
<About activeSection={activeSection}/>
<Skills activeSection={activeSection}/>
<Projects activeSection={activeSection}/>
<Contact activeSection={activeSection}/>
</div>
</React.Fragment>
);
const Buttons = ({ onToggle }) => (
<div className="buttons">
<button name='start' onClick={onToggle}>Start</button>
<button name='about' onClick={onToggle}>About</button>
<button name='skills' onClick={onToggle}>Skills</button>
<button name='contact' onClick={onToggle}>Contact</button>
</div>
);
class App extends Component {
constructor(props) {
super(props);
this.state = {
activeSection: "",
};
this.handleToggleSection = this.handleToggleSection.bind(this);
};
handleToggleSection(e) {
const {name} = e.target;
this.setState(() => ({
activeSection: name
}));
};
render() {
return (
<div className="App">
<Buttons onToggle={this.handleToggleSection}/>
<Main activeSection={this.state.activeSection}/>
</div>
);
};
};
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Resources