Select image and Scroll through the page when user clicks - javascript

I have a list of 50 photos which I will get from an API. When the user clicks on any photo it should open up on the right side component.
When a photo in the right side component is clicked it should scroll down (if the image is not at top) the the place in the page where that image is present.
import React from 'react';
import axios from 'axios';
import '../App.css';
class Dashboard extends React.Component {
constructor(props) {
super(props);
this.state={
image:'abc',
}
}
imageload(appendimage){
this.setState({
image:appendimage
})
}
componentWillMount() {
axios.get('http//api')
.then((res) => this.setState({
results: res.data
}))
.catch((error)=>{
console.log(error)
})
}
render() {
return (
<div>
<div className="left">
<img width="373" height="230" alt="img3" id="mytarget"
onClick={this.imageload.bind(this,"https://i.ytimg.com.jpg")}
src="https://i.ytimg.com/vi/.jpg"
/>
</div>
<div className="right>
<img src={this.state.ima} height={510} width={400}
alt="placeholderimg"
style={{position:"fixed"}}
className={classes.staticimg}
onClick={this.imageredirect.bind(this)}
/>
</div>
</div>
);
}
}
export default withStyles(style)(Dashboard);

Related

React: Toggle content in another component

I'm new to React and I'm stuck in this problem. I have a toggle component that is rendering a button to show/hide data aswell as the data that is being rendered.
I want to separate both the button and the data so I can display the content in another component, and being able to hide it and show it from the toggle component, if it makes sense.
Here is a picture to demonstrate what I'm wishing to do.
Toggle Example
The toggleComponent.js that contains the button and the data :
import React, { Component } from 'react';
export default class toggleComponent extends React.Component{
constructor(){
super();
this.state={
isShowBody: false
}
}
handleClick = (event) => {
this.setState({ isShowBody: !this.state.isShowBody })
}
checkbox = () => {
return (
<div >
<span className="switch switch-sm" >
<label>
<input type="checkbox" name="select" onClick={this.handleClick.bind(this)}/>
<span />
</label>
</span>
</div>
)
}
content = () => {
return (
<div>
Displaying text
</div>
)
}
render() {
return (
<div>
{this.checkbox()}
{this.state.isShowBody && this.content ()}
</div>
);
}
}
Just make another component named content.js. Import ContentComponent inside ToggleComponent and render it using flag.
Stackblitz Demo
Solution:
Toggle Component
import React, { Component } from "react";
import ContentComponent from "./content.js";
export default class toggleComponent extends React.Component {
constructor() {
super();
this.state = {
isShowBody: false
};
}
handleClick = event => {
this.setState({ isShowBody: !this.state.isShowBody });
};
checkbox = () => {
return (
<div>
<span className="switch switch-sm">
<label>
<input
type="checkbox"
name="select"
onClick={this.handleClick.bind(this)}
/>
<span />
</label>
</span>
</div>
);
};
render() {
return (
<div>
{this.checkbox()}
{this.state.isShowBody && <ContentComponent />}
</div>
);
}
}
Content Component
import React, { Component } from "react";
export default class ContentComponent extends React.Component {
content = () => {
return <div>Displaying text</div>;
};
render() {
return <div>{this.content()}</div>;
}
}

How do you change state of a react component from a different component?

I am trying to understand how to pass props to components in react. I am new to react and I have been struggling to understand the fundamentals of state.
I would like a button to display an overlay and populate the "content" of that overlay with some arbitrary text for now.
I am trying to use a prop called doWeDisplay as variable to hold a css value of "none" or "absolute" (to hide and show the component) and a prop called "content" for the content of the overlay.
Here is my code, could someone please point me in the right direction. I need that eureka moment for it to click in place and my head is all over the place trying to get this.
app.js
import React from 'react';
import Overlay from './components/overlay';
import Header from './components/header';
import Body from './components/body';
import Footer from './components/footer';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
console.log("App props", this.props)
return (
<div className="App">
<Overlay />
<Header />
<Body content={ this.props.appContent } />
<Footer />
</div>
);
}
}
export default App;
body.js
import React from 'react';
import './body.css';
import Overlay from './overlay'
class Body extends React.Component {
constructor(props) {
super(props);
this.state = {
doWeDisplay : "absolute",
content : "Go on"
};
}
render() {
function handleClick(e) {
console.log("Click")
Overlay.setState((state, props) => ({
doWeDisplay : "absolute",
content : "Go on"
}))
}
console.log("Body props ", this.props);
return (
<div className="App-Body">
<p>Here is the body of the page.</p>
<button onClick={ handleClick }>Click me</button>
</div>
);
}
}
export default Body
overlay.js
import React from 'react';
import './overlay.css';
class Overlay extends React.Component {
constructor(props) {
super(props);
this.state = {
doWeDisplay : props.doWeDisplay,
content : props.doWeDisplay
};
}
render() {
console.log("Overlay props " , this.props)
return (
<div className="App-Overlay" style={{ display: this.state.doWeDisplay }}>
{ this.state.content }
</div>
);
}
}
export default Overlay
When you have sibling components that can change other's state, you will need to handle that state in the parent component (in your case it is App).
So the handleClick() function should be in the parent component, and the state itself of the variables doWeDisplay and content should be in App as well.
Then, you can pass that function to Body as a prop, so you could trigger it on click within the Body component. I called that prop clickFunc in my example.
Finally, the last thing you will need is to pass the current state to Overlay as props, so I passed the doWeDisplay and content as different props, that gets the value from App's state.
It should look something like this:
app.js
import React from 'react';
import Overlay from './components/overlay';
import Header from './components/header';
import Body from './components/body';
import Footer from './components/footer';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
doWeDisplay: "absolute",
content: "Go on"
};
}
handleClick = () => {
console.log("Click");
this.setState({
doWeDisplay: "absolute",
content: "Go on CHANGED!"
});
};
render() {
console.log("App props", this.props);
return (
<div className="App">
<Overlay
doWeDisplay={this.state.doWeDisplay}
content={this.state.content}
/>
<Body clickFunc={this.handleClick} content={this.props.appContent} />
</div>
);
}
}
export default App;
body.js
import React from 'react';
import './body.css';
import Overlay from './overlay'
class Body extends React.Component {
render() {
console.log("Body props ", this.props);
return (
<div className="App-Body">
<p>Here is the body of the page.</p>
<button onClick={() => this.props.clickFunc()}>Click me</button>
</div>
);
}
}
export default Body
overlay.js
import React from 'react';
import './overlay.css';
class Overlay extends React.Component {
render() {
console.log("Overlay props ", this.props);
return (
<div className="App-Overlay" style={{ display: this.props.doWeDisplay }}>
{this.props.content}
</div>
);
}
}
export default Overlay
Here's codesandbox

How to get element ID to show all data from clicked element using react-router?

So, I have my component where it shows all of the products. What I want now is, when I click on one of the products to open component for displaying all of the data of clicked product. When I click, it shows me this url http://localhost:3000/products/1.
How can I get data with this id at the end of url
This is component that fetch all the data from mysql:
import React from "react";
import {Link} from "react-router-dom"
class Home extends React.Component{
constructor(){
super()
this.state = {
products: [],
isLoaded: false
}
}
componentDidMount(){
fetch("/home")
.then(res => res.json())
.then(result =>{
return(
this.setState({
products: result,
isLoaded: true
})
)
})
}
render(){
if(!this.state.isLoaded){
return(
<h1>Loading...</h1>
)
}
return (
<div className="row text-center">
{this.state.products.map(elements =>
<div className="col-lg-6">
<h1>
<Link to={`products/${elements.id}`}>{elements.name}</Link>
</h1>
</div>
)}
</div>
)
}
}
export default Home;
And how can I get that clicked product information here:
import React from "react";
class ProductDesc extends React.Component{
constructor(){
super()
}
componentDidMount(){
fetch()
.then(res => res.json())
.then(result =>{
console.log(result)
})
}
render(){
return(
)
}
}
export default ProductDesc;
In your Router you should have a Route that renders ProductDesc.
<Route path="products/:id" component={ProductDesc} />
This will add route props to the rendered component. You can access the route parameter from the match prop.
ProductDesc
this.props.match.params.id

How to cancel mutlicall of componentDidMount() in ReactJS component?

I have created a component DATA which has componentDidMount() function to get data from the API. After this, I import it into the main component. The main component has a render method where I have a simple structure: 1st div - Some info and imported component DATA, 2nd div is a button which opens a modal, which has some text and button which closes this modal dialog box.
I have read that componentDidMount() is called only once after the component is rendered.
But when I push button to open my modal page at the same time componentDidMount() is called again.
What I need is that componentDidMount() don't run when I open the modal box. But run only when the page is rendered or refreshed.
main component
import React from "react";
import Modal from '../components/modal/form'
import Actions from '../data/Actions'
class MainPage extends React.Component{
constructor(){
super();
this.state = {
show: false,
};
this.showModal = this.showModal.bind(this);
//this.setSearchTopStories = this.setSearchTopStories.bind(this);
};
showModal = e => {
this.setState({
show: !this.state.show
});
};
render(){
return <div>
<div className="topDescribtion">
<h2>descr</h2>
<Actions />
</div>
<div className="btnNewTransaction">
<button onClick={e => {
this.showModal();
}}>
show Modal
</button>
<Modal onClose={this.showModal} show={this.state.show}>
Mdl--
</Modal>
</div>
<div className="transactionList"></div>
</div>
}
}
export default MainPage;
DATA component
import React, { Component } from "react";
import Modal from '../components/modal/form'
const PATH_BASE = 'my URL which I give data in JSON format and it works fine';
class Actions extends React.Component{
constructor(){
super();
this.state = {
result:null
};
this.setSearchTopStories = this.setSearchTopStories.bind(this);
}
setSearchTopStories(result) {
this.setState({ result });
};
componentDidMount() {
fetch(`${PATH_BASE}`)
.then(response => response.json())
.then(result => this.setSearchTopStories(result))
.catch(error => error);
};
render(){
const { searchTerm, result } = this.state;
console.log(result);
return <div></div>;
}
}
export default Actions;
The componentDidMount() method in Actions component is being called again as your parent component is re-rendered and so will the child. To stop this make your Actions component a Pure component instead.
A Pure component is only re-rendered when there is a change in state or props of that component.
Replace
class Actions extends React.Component{
with
class Actions extends React.PureComponent {
Hope it helps!!

React component isn't loading properly

I am trying to build a single-page React app, which loads content from an API using Axios.
I have created the component called "Importapi" and called it in the App.js file as yet nothing is showing up.
Does anyone have an idea as to why this is happening?
Importapi - Import Component
import React, { Component } from 'react';
import axios from "axios";
import "./index.css";
export class Importapi extends Component {
constructor() {
super();
this.state = {
trails: [],
}
//this.handleSubmit = this.handleSubmit.bind(this);
};
componentDidMount() {
axios.get("https://www.hikingproject.com/data/get-trails?lat=46.589519&lon=7.912295&maxDistance=100&maxResults=15&key=200490043-7294b2e6976c168d4e44877bf48ef553")
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<div className="container2">
<div className="container1">
{this.state.trails}
</div>
</div>
)
};
};
export default Importapi;
App.js - Single page React App
import React from 'react';
import logo from './logo.png';
import './App.css';
import Import from './import.js';
import Importapi from './axios-api'
function App() {
return (
<div className="App">
<header>
<title>Hikeero</title>
</header>
<nav>
<div className="nav-bar logo">
<button>BACK</button>
</div>
<div className="nav-bar items">
</div>
<button> HOME </button>
</nav>
<div align="right" >
<br/>
</div>
<h1>Hikeero.</h1>
<Import />
<Importapi />
<header className="App-header">
<a
className="App-link"
href="/import.js/"
target="_blank"
rel="noopener noreferrer"
>
<br/>
<br/>
<br/>
Click to Start
</a>
</header>
</div>
);
}
export default App;
There are no errors, just the API information isn't showing up.
You have to do this.setState({ trails : response.data }) just below console.log(response.data); to show the content on component. Thus the API response will be set into state with key name of trails.
componentDidMount() {
axios.get("https://www.hikingproject.com/data/get-trails?lat=46.589519&lon=7.912295&maxDistance=100&maxResults=15&key=200490043-7294b2e6976c168d4e44877bf48ef553")
.then(response => {
// here once you receive response
// put the response data into state of the component
// as written below
this.setState({trails: response.data})
})
.catch(error => {
console.log(error);
});
}

Categories

Resources