Loader Component:
import React, { Component } from "react";
export class Loader extends Component {
state = {
isLoading: true,
};
componentDidMount() {
setTimeout(() => {
this.setState({ isLoading: false });
}, 500);
}
render() {
return (
<span className={"loading " + (this.state.isLoading ? "show" : "hide")}>
<span className="loading-bg"></span>{" "}
<img src="img/loader.gif" alt="Loading" />{" "}
</span>
);
}
}
export default Loader;
Layout Component:
import React, { Component } from "react";
import { Container } from "reactstrap";
import { NavMenu } from "./NavMenu";
import Loader from "./common/Loader";
import Footer from "./Footer";
export class Layout extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<NavMenu />
<Container fluid>
<Loader />
{this.props.children}
<footer className="d-flex justify-content-between align-items-center pt-3">
<Footer />
</footer>
</Container>
</div>
);
}
}
So every component will have loader and it will hide once componentDidMount()....
I want show loader when another actions like form submission and opening a modal. How to acheive it form form or modal component.
I want to reuse the same Loader component.
the State of Loading should be in the parent components in this case it should be in the layout component and then you pass it as a prop to the Loader component.
ofcourse you should be showing the loader component of state is true and hide if false.
Related
I have a component where a list of pictures is rendered and it works perfectly fine :
import { Component} from 'react'
import Header from '../Home/Header'
import Footer from '../Home/Footer'
import PhotoItems from './objet'
class Photos1930 extends Component {
render() {
return (
<div>
<Header />
<h2 className='titre bloc'>Photos 1930</h2>
<div className='bloc bloc__photo'>
{PhotoItems.map((val, key) => {
let id = val.id
let url = val.url
let lienImage = "/galerie/:" + (val.id)
return <div key={id}>
<a href={lienImage}>
<img className='photo' alt='Photo Charles-Quint' src={url}></img>
</a>
</div>
})}
</div>
<Footer />
</div>
)
}
}
export default Photos1930
I want to create an other component where i can load a specific picture when user click on a picture from the precedent list. I use the same logic but for some reason the picture doesn't load. I don't have any errors in my console but on my page i just have the standard icon for image with my alt.
All the pictures are on public folder.
I just don't understand why is it working on one component but not on the other one.
import { Component } from 'react'
import Header from '../Home/Header'
import Footer from '../Home/Footer'
import PhotoItems from './objet'
const url = window.location.pathname
const justId = parseInt((url.split(':')[1]))
function specificId(photo) {
return photo.id === (justId)
}
let justUrl = (PhotoItems.find(specificId).url)
console.log(justUrl)
class PickPhoto extends Component {
render() {
return (
<div>
<Header />
<div>
<h1>{justId}</h1>
<img className="bigPhoto" alt="Charles-Quint" src={justUrl}></img>
</div>
<Footer />
</div>
)
}
}
export default PickPhoto
EDIT1 : Here's my github repo : https://github.com/FranMori/CharlesQuint
and here's my netlify link : https://stoic-bohr-810e13.netlify.app/
You can click on "Galerie Photos" and then click on any picture to see the problem.
in your repo, this.justUrl is undefined. You need to add justUrl in the component's state and update it dynamically inside componentDidMount like below. I also added a / in src={/${this.state.justUrl}}
import { Component } from 'react'
import Header from '../Home/Header'
import Footer from '../Home/Footer'
import PhotoItems from './objet'
class PickPhoto extends Component {
constructor() {
super()
this.state = { justUrl: "" };
}
componentDidMount() {
const url = window.location.pathname
const justId = parseInt((url.split(':')[1]))
function specificId(photo) {
return photo.id === justId
}
let justUrl = (PhotoItems.find(specificId).url)
console.log(justUrl)
this.setState({justUrl})
}
render() {
return (
<div>
<Header />
<div>
<h1>{this.justId}</h1>
<img className="bigPhoto" alt="Charles-Quint" src={`/${this.state.justUrl}`}></img>
</div>
<Footer />
</div>
)
}
}
export default PickPhoto
i have an app component where map over my data an return a component, I want to make app the homepage that displays the component i return
import React, { Component } from "react";
import data from "./data";
import Asteriods from "./components/Asteroids";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Header from "./components/Header";
import "./App.css";
class App extends Component {
state = {
// calculations: [],
asteroids: data,
};
render() {
return (
<div className="space">
<Header />
{this.state.asteroids.map((item) => (
<Asteriods key={item.id} item={item} />
))}
</div>
);
}
}
export default App;
I also have a component that where i want to link to that other component and still pass props to the stock component
import React, { Component } from "react";
import Stock from "./Stock";
class AsteroidDetails extends Component {
render() {
return (
<div className="popup">
<div className="popup\_inner">
<button onClick={this.props.closePopup}>X</button>
<p> - Name: {this.props.asteroid.name}</p>
<p> - Type: {this.props.asteroid.type}</p>
<p> - Mass: {this.props.asteroid.mass}</p>
Link to vieuw stock
<Stock
// chemPerDay={this.props.chemPerDay}
{...this.props}
// remainingMassPerday={this.props.remainingMassPerday}
// asteroidYieldPerDay={this.props.asteroidYieldPerDay}
// remainingMpct={this.props.remainingMpct}
/>
</div>
</div>
);
}
}
export default AsteroidDetails;
how can i use react router in both of these cases ?
The main form page where the login and Sign up form will live give undefined. How can I tried to render forms to this MainScreen.js file when the user click on in the navbar.
MainScreen.js (Where the forms are live)
import React from 'react';
import RegisterBox from '../Forms/Register'
import LoginBox from '../Forms/Login'
// This is the page for form to live on
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoginOpen: true,
isRegisterOpen: false
};
}
render() {
return (
<div>
<div className="root-container">
{this.state.isLoginOpen && <LoginBox/>}
{this.state.isRegisterOpen && <RegisterBox/>}
</div>
</div>
)
}
}
export default App;
Navigation.js (Where the button is clicked but are not being defined anywhere so cannot find the page to take me to the forms.)
import React from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import Dropdown from "../components//pages/dropdowns/dropdowns";
import hamburger from "../images/menu.svg"
class Navigation extends React.Component {
constructor(props) {
super(props);
this.state = {
isExpanded: false
};
}
handleToggle(e) {
e.preventDefault();
this.setState(prevState => ({
isExpanded: !prevState.isExpanded, // negate the previous expanded state
}));
}
render() {
const { isExpanded } = this.state;
return (
<Router>
<div className="NavbarContainer">
<div className="mobilecontainer LeftNav">
<h2 className="BrandName LeftNav mobileboxmenu inline FarRight">Kommonplaces</h2>
<div className="hamburger inlinev" >
<img
onClick={e => this.handleToggle(e)}
alt="menubtn"
src={hamburger}
/>
</div>
</div>
<ul className={`NavBar collapsed ${isExpanded ? "is-expanded" : ""}`}>
<Dropdown/>
<li className="RightNav"><Link to="/">Host Your Space</Link></li>
<li className="RightNav"><Link to="/">About Us</Link></li>
<li className="RightNav"><Link to="/">Contact Us</Link></li>
<div className="btnflexright">
<button
className={"controller " + (this.state.isLoginOpen
? "selected-controller"
: "")}
onClick={this
.props
.showLoginBox}>
Login
</button>
<button
className={"controller " + (this.state.isRegisterOpen
? "selected-controller"
: "")}
onClick={this
.props
.showRegisterBox}>
Sign up
</button>
</div>
</ul>
</div>
</Router>
);
}
}
export default Navigation;
You need to do a couple things:
add some couple methods to your App component to set the state.
import and render the Navigation component in your App component (so you can pass your methods in as functions. you could use the Context API but it's more complicated...)
pass those methods as functions to your Navigation component (and pass the state in as props if you need them too)
call the methods through the props of your Navigation component
In your App component:
import React from 'react';
import RegisterBox from '../Forms/Register'
import LoginBox from '../Forms/Login'
import Navigation from './Navigation'
// This is the page for form to live on
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoginOpen: true,
isRegisterOpen: false
};
}
/*
* 1. add these two methods here to modify the state of `App`
*/
showLoginBox() {
this.setState({ isLoginOpen: true });
}
showRegisterBox() {
this.setState({ isRegisterOpen: true });
}
render() {
return (
<div>
<div className="root-container">
{
/* 2. render the `Navigation` component in `App` */
/* 3. pass your methods in as function props to `Navigation` */
}
<Navigation
isLoginOpen={this.state.isLoginOpen}
isRegisterOpen={this.state.isRegisterOpen}
showLoginBox={this.showLoginBox.bind(this)}
showRegisterBox={this.showRegisterBox.bind(this)}
/>
{this.state.isLoginOpen && <LoginBox/>}
{this.state.isRegisterOpen && <RegisterBox/>}
</div>
</div>
)
}
}
export default App;
Now you can call those methods from your Navigation component...
{ /* 4. call the prop functions in `Navigation` component */ }
<button
className={"controller " + (this.props.isLoginOpen ? "selected-controller" : "")}
onClick={this.props.showLoginBox}>
Login
</button>
<button
className={"controller " + (this.props.isRegisterOpen ? "selected-controller" : "")}
onClick={this.props.showRegisterBox}>
Sign up
</button>
I'm not getting props in my Nav component. Odd thing is, 'this.props.history.push' is working in my other components.
The same function is working in my other components, but when I try to call the push function, I'm getting 'err in logout TypeError: Cannot read property 'push' of undefined'. The 'this.props' object is logging as '{}'.
Any help is appreciated, thank you.
import React from 'react'
import logo from 'logo.png'
import css from './Nav.module.scss'
import { Link } from 'react-router-dom'
import Cookies from 'js-cookie'
import axios from 'axios'
class Nav extends React.Component {
constructor(props) {
super(props)
this.state = {
loggedIn: false
}
console.log(this.props)
}
_handleLogout = () => {
// const self = this
console.log(this.props)
axios.get('http://localhost:8080/logout', {
withCredentials: true
})
.then(res => {
console.log(res)
console.log('logout')
if (Cookies.get('sid') === undefined) {
this.props.history.push('/')
}
console.log(this.props)
})
.catch(err => {
console.log('err in logout', err)
})
}
render() {
return (
<div className={css.nav}>
<div className={css.leftPart}>
<Link to="/">
<div className={css.brandicon}>
<img src={logo} alt="Logo" />
</div>
<div className={css.brandname}>
somebrand
</div>
</Link>
</div>
<div className={css.rightPart}>
{
Cookies.get('sid') === undefined ?
<Link to="/login">
<div className={css.loginButton}>
Login
</div>
</Link>
:
<div className={css.logoutButton} onClick={this._handleLogout}>
Logout
</div>
}
</div>
</div>
)
}
}
export default Nav
My Nav component is only referenced once in my Layout component:
import React from 'react'
import Nav from 'components/Nav/Nav'
import css from './BasicLayout.module.scss'
class Basic extends React.Component {
render() {
return (
<div className={css.page}>
<Nav />
<div className={css.content}>
{this.props.children}
</div>
</div>
)
}
}
export default Basic
history and location are special props injected by React Router's HOC withRouter
import { withRouter } from 'react-router-dom'
class Nav extends React.Component{
render(){
const { history, location } = this.props
return <div>{`I'm at ${location.pathname}`}</div>
}
}
export default withRouter(Nav)
It works for functional components as well
export const Component = withRouter(({ history, location })) =>(
<div>{`I'm at ${location.pathname}`}</div>
)
I want to make when i click button, show modal in different class.
how to make it this?
import React, { Component } from 'react';
import addmodal from './addmodal';
class page extends Component {
...//skip
handleAdd= () =>{
//...how?
}
render(){
return (
<button onClick={this.handleAdd} > Add </button>
)
}
}
import React, { Component } from 'react';
class addmodal extends Component {
// ... skip
render(){
return(
<modal inOpen={this.state.isopen} >
...//skip
</modal>
)
}
}
export default addmodal;
I can't call this addmodal...
how to call modal?
First, your variable naming is terrible. I fixed it for you here. The state that dictates if modal is open must be on the parent component since you have your trigger there. Then, pass it as props to the modal component. Here is the fixed code for you:
import React, { Component } from 'react';
import AddModal from './addmodal';
class Page extends Component {
constructor(){
super();
this.state = { isModalOpen: false };
}
...//skip
handleAdd= () =>{
this.setState({ isModalOpen: true });
}
render(){
return (
<div>
<button onClick={this.handleAdd} > Add </button>
<AddModal isOpen={this.state.isModalOpen} />
</div>
)
}
}
import React, { Component } from 'react';
class AddModal extends Component {
// ... skip
render(){
return(
<modal inOpen={this.props.isOpen} >
...//skip
</modal>
)
}
}
export default AddModal;
what about using trigger. Its very usefull.
<Modal trigger={ <button onClick={() => onCLickPay()} className={someting}> When clicked here modal with show up</button> }`enter code here` >