I want to change rendered component place each time the route (url) changes.
e.g. I have 3 blocks: Home, Works, Contacts. When url is site.com/home the content renders in Home block, when url is site.com/works the content moves to Works block and so on.
I did a kind of what I want but it renders the whole page when It seems more optimal to just moves new content.
So can you suggest better decisions?
The whole project you can get and run locally from here: https://github.com/g1un/reactjs-site
What it looks like (buggy regarding routing) you can see here: http://g1un.ru/reactjs/
I paste the main files below.
index.js
import React from 'react';
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import style from './../scss/style.scss';
import { Header } from './components/Header';
import { About } from './components/About';
import { Works } from './components/Works';
import { Contacts } from './components/Contacts';
import { NotFound } from './components/NotFound';
class App extends React.Component {
render() {
return (
<Router>
<div className="container">
<Switch>
<Route exact path="/" component={About}/>
<Route exact path="/works" component={Works}/>
<Route exact path="/contacts" component={Contacts}/>
<Route component={NotFound}/>
</Switch>
</div>
</Router>
);
}
}
render(<App />, window.document.getElementById('app'));
About.js (Works.js, Contacts.js are similar)
import React from 'react';
import DocumentTitle from 'react-document-title';
import { Header } from './Header';
export class About extends React.Component {
render() {
return (
<DocumentTitle title='About'>
<Header currentPath={this.props.location.pathname}>
<h1>
About
</h1>
</Header>
</DocumentTitle>
);
}
}
Header.js
import React from 'react';
const PATHS = ['/', '/works', '/contacts'];
const PAGES = ['About', 'Works', 'Contacts'];
import { HeaderItem } from './HeaderItem';
export class Header extends React.Component {
constructor(props) {
super();
this.currentPath = props.currentPath;
this.content = props.children;
this.paths = PATHS;
this.pages = PAGES;
}
render() {
return (
<header className="header">
<nav className="nav">
<div className="nav__list">
{this.paths.map((path, i) => {
return <HeaderItem key={i} currentPath={path} currentPage={this.pages[i]} pageContent={path === this.currentPath ? this.content : ''}/>;
})}
</div>
</nav>
</header>
);
}
}
HeaderItem.js
import React from 'react';
import { NavLink } from 'react-router-dom';
export class HeaderItem extends React.Component {
render() {
return (
<div className={"nav__item " + (this.props.pageContent ? "_active" : "")}>
<NavLink className="nav__link" exact activeClassName="_active" to={this.props.currentPath}>
{this.props.currentPage}
</NavLink>
{this.props.pageContent ? <div className="nav__content content">{this.props.pageContent}</div> : ''}
</div>
);
}
}
I've found the desicion myself.
The fact is that I can't use any blocks inside <Switch/>, so I've simply used <Route>s without <Switch/>, putting them in any blocks I need.
And for '404' page I've created <Switch/> block with same Routes inside without component attributes except one for '404' page.
Now in each HeaderItem I can control whether its content is visible or not.
New index.js:
import React from 'react';
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import DocumentTitle from 'react-document-title';
import style from './../scss/style.scss';
import { Header } from './components/Header';
import { HeaderItem } from './components/HeaderItem';
import { About } from './components/About';
import { Works } from './components/Works';
import { Contacts } from './components/Contacts';
import { NotFound } from './components/NotFound';
const PATHS = ['/', '/works', '/contacts'];
const PAGES = ['About', 'Works', 'Contacts'];
const COMPONENTS = [About, Works, Contacts];
class App extends React.Component {
constructor() {
super();
this.paths = PATHS;
this.pages = PAGES;
this.components = COMPONENTS;
this.state = {
documentTitle: this.getDocumentTitle()
};
}
updateDocumentTitle(pageTitle) {
if(this.state.documentTitle === pageTitle) return;
this.setState({
documentTitle: this.getDocumentTitle()
});
}
getDocumentTitle() {
let pathIndex = this.paths.indexOf(window.location.pathname);
if(pathIndex === -1) {
return 'Not found';
} else {
return this.pages[pathIndex];
}
}
render() {
return (
<DocumentTitle title={this.state.documentTitle}>
<Router>
<div className="container">
<Switch>
{this.paths.map((path, i) => {
return <Route key={i} exact path={path}/>;
})}
<Route render={() => <NotFound text="Error 404"/>}/>
</Switch>
<Header>
{this.paths.map((path, i) => {
return (
<HeaderItem
key={i}
routePath={path}
pageTitle={this.pages[i]}
updateDocumentTitle={this.updateDocumentTitle.bind(this)}
>
<Route exact path={path} component={this.components[i]}/>
</HeaderItem>
);
})}
</Header>
<Switch>
{this.paths.map((path, i) => {
return <Route key={i} exact path={path}/>;
})}
<Route render={() => <NotFound text="Page not found"/>}/>
</Switch>
</div>
</Router>
</DocumentTitle>
);
}
}
render(<App />, window.document.getElementById('app'));
New HeaderItem.js:
import React from 'react';
import { NavLink } from 'react-router-dom';
import { Content } from './Content';
import { About } from './About';
import { Works } from './Works';
import { Contacts } from './Contacts';
const COMPONENTS = [About, Works, Contacts];
const PAGES = ['About', 'Works', 'Contacts'];
export class HeaderItem extends React.Component {
constructor(props) {
super();
this.path = props.routePath;
this.content = props.children;
this.page = props.pageTitle;
this.components = COMPONENTS;
this.pages = PAGES;
this.index = this.pages.indexOf(this.page);
this.updateDocumentTitle = props.updateDocumentTitle;
this.state = {
isActive: this.path === window.location.pathname
};
}
componentWillUpdate() {
//to change page title if this component is active
if(this.path === window.location.pathname) {
this.updateDocumentTitle(this.page);
}
this.saveRouteComponent();
}
isActive() {
return this.path === window.location.pathname;
}
saveRouteComponent() {
if(this.state.isActive || this.path !== window.location.pathname) return;
//once opened route get 'isActive' state and its content will not removed when this route is deactivated
this.setState({ isActive: true });
}
render() {
return (
<div className={"nav__item " + (this.isActive() ? "_active" : "")}>
<div className="nav__item-wrapper">
<NavLink className="nav__link" exact activeClassName="_active" to={this.path}>
{this.page}
</NavLink>
</div>
{(this.isActive() || this.state.isActive) ? <div className="nav__content"><Content pageTitle={this.page}>{this.state.isActive ? React.createElement(this.components[this.index]) : this.content}</Content></div> : ''}
</div>
);
}
}
Related
I'm trying to load component asynchronicity with appropriate component base on the ReactCSSTransitionGroup package by this example: https://codesandbox.io/s/zkqlq2vo?from-embed
So I combined all to one component as the following:
import React, { Component } from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import './PageShell.less';
const PageShell = (importComponent) => {
return class extends Component {
state = {
component: null
}
componentDidMount() {
importComponent()
.then(cmd => {
this.setState({ component: cmd.default });
})
.catch({});
}
render() {
const C = this.state.component;
const component = C ? (<C {...this.props} />) : null;
return (
<ReactCSSTransitionGroup
transitionAppear={true}
transitionAppearTimeout={600}
transitionEnterTimeout={600}
transitionLeaveTimeout={200}
transitionName={`Slide${Math.random() >= 0.5 ? 'In' : 'Out'}`}>
{component}
</ReactCSSTransitionGroup>
);
}
};
};
export default PageShell;
And on my App.js:
import React, { Component } from 'react';
import Layout from './hoc/Layout/Layout';
import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder';
import Logout from './containers/Auth/Logout/Logout';
import AsyncComponent from './hoc/AsyncComponent/AsyncComponent';
const asyncCheckout = AsyncComponent(() => {
return import('./containers/Checkout/Checkout/Checkout');
});
const asyncOrders = AsyncComponent(() => {
return import('./containers/Orders/Orders');
});
const asyncAuth = AsyncComponent(() => {
return import('./containers/Auth/Auth/Auth');
});
class App extends Component {
render() {
let routes = (
<Switch>
<Route path="/auth" component={PageShell(asyncAuth)} />
<Route path="/" exact component={PageShell(BurgerBuilder)} />
<Redirect to="/" />
</Switch>
);
return (
<div>
<Layout>
{routes}
</Layout>
</div>
);
}
}
export default App;
For some reason that i don't understand, the transition in my upgraded PageShell component not working, like in the example from codesandbox, and i can't figure out why is that.
I'm using react router v4 and using the render prop to load up a settings component that has a dynamic input (a value prop based on the state with an onChange handler). When I load the component without using react router, typing into the input field is dynamic, and changes state as you type. But when I use react router, each character press re-renders the entire settings component, causing the input field to lose focus. Not sure why this is happening, since I'm using the render prop instead of the component prop on the <Route /> component. Any help would be appreciated!
My App Component:
import React, { Component, Fragment } from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "../Home/Home";
import Header from "../Header/Header";
import AppSettings from "../AppSettings/AppSettings";
import NotFound from "../NotFound/NotFound";
import { secsToMs, minsToMs, msToTime } from "../../helpers";
import "./App.css";
class App extends Component {
state = {
settings: {
time: {
break: minsToMs(5),
relax: minsToMs(15),
work: minsToMs(25)
},
trackLength: 2,
autoplay: true
},
defaultSettings: {
time: {
break: minsToMs(5),
relax: minsToMs(15),
work: minsToMs(25)
},
trackLength: 4,
autoplay: false
},
time: minsToMs(25),
totalTime: minsToMs(25),
timerPlaying: false,
track: {
tasksCompleted: 0,
breaksCompleted: 0,
timerName: "work"
}
};
updateSettings = (key, updatedSetting) => {
let settings = { ...this.state.settings };
settings.time[key] = updatedSetting;
this.setState({ settings });
};
//...other App methods
render() {
const MainAppContent = ({ location }) => (
<Fragment>
<Header track={this.state.track} location={location} />
<Home
timerPlaying={this.state.timerPlaying}
totalTime={this.state.totalTime}
time={this.state.time}
track={this.state.track}
trackLength={this.state.settings.trackLength}
startTimer={this.startTimer}
pauseTimer={this.pauseTimer}
resetTimer={this.resetTimer}
skipTimer={this.skipTimer}
/>
<AppSettings
settings={this.state.settings}
updateSettings={this.updateSettings}
restoreDefaultSettings={this.restoreDefaultSettings}
/>
</Fragment>
);
const SettingsAppContent = ({ location }) => (
<Fragment>
<Header track={this.state.track} location={location} />
<AppSettings
settings={this.state.settings}
updateSettings={this.updateSettings}
restoreDefaultSettings={this.restoreDefaultSettings}
/>
</Fragment>
);
return (
<main className="App">
<BrowserRouter>
<Switch>
<Route exact path="/" component={MainAppContent} />
<Route
path="/settings"
render={props => <SettingsAppContent {...props} />}
/>
<Route component={NotFound} />
</Switch>
</BrowserRouter>
</main>
);
}
}
export default App;
My AppSettings Component:
import React, { Component, Fragment } from "react";
import RangeSlider from "../RangeSlider/RangeSlider";
import { minsToMs } from "../../helpers";
import "./AppSettings.css";
class Settings extends Component {
render() {
return (
<Fragment>
<h1>Settings</h1>
{Object.keys(this.props.settings.time).map(key => (
<RangeSlider
name={key}
key={key}
time={this.props.settings.time[key]}
updateSettings={this.props.updateSettings}
/>
))}
<button onClick={this.props.restoreDefaultSettings}>
Revert to Default
</button>
</Fragment>
);
}
}
export default Settings;
My Input Component:
import React, { Component } from "react";
import { msToTime, minsToMs } from "../../helpers";
import "./RangeSlider.css";
class RangeSlider extends Component {
onSettingsChange = e => {
let rangeValue = parseInt(e.currentTarget.value);
if (rangeValue > 60) {
rangeValue = 60;
} else if (rangeValue < 1 || rangeValue === NaN) {
rangeValue = 1;
}
let rangeValueMs = minsToMs(rangeValue);
let key = e.currentTarget.name;
let updatedSetting = rangeValueMs;
const updatedSettings = {
...this.props.settings,
[key]: rangeValueMs
};
console.log("updatedSettings", updatedSettings);
this.props.updateSettings(key, updatedSetting);
};
render() {
const { name, time } = this.props;
return (
<div>
<input
type="number"
min="1"
max="60"
value={msToTime(time).m}
className="text-box"
name={name}
onChange={this.onSettingsChange}
/>
</div>
);
}
}
export default RangeSlider;
I am sorry for my stupid question but i am really new in react and this problem make me stuck for days. I am kinda confused to make a login page in reactjs. my app.js code is like this :
import React from 'react';
import {HashRouter as Router, Route} from 'react-router-dom';
import asyncComponent from './AsyncComponent';
import AppShell from './AppShell';
import Login from './login/Login';
const Dashboard = asyncComponent(() => {
return import(/* webpackChunkName: "dashboard" */ './dashboard/Dashboard')
.then(module => module.default);
});
const LoginPage = asyncComponent(() => {
return import(/* webpackChunkName: "login" */ './login/Login')
.then(module => module.default);
});
class App extends React.Component {
render() {
return (
<Router>
<AppShell>
<div>
<Route exact path="/" component={Dashboard} />
<Route path="/login" component={LoginPage} />
</div>
</AppShell>
</Router>
);
}
}
export default App;
And this is my AppShell code :
import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import {MuiThemeProvider} from 'material-ui/styles';
import {AppBar, Drawer, MenuItem} from 'material-ui';
import {DashboardIcon} from './icon/Icons';
import ArrowDropRight from 'material-ui/svg-icons/navigation-arrow-drop-right';
const ContentStyle = {
width: '90%',
margin: 'auto',
marginTop: '30px'
};
class SidebarDrawer extends React.Component {
componentDidMount() {
let frameCount = 0;
const open = () => (frameCount++ > 0) ? this.props.onMounted() :
requestAnimationFrame(open);
requestAnimationFrame(open);
}
render() {
return (
<Drawer
docked={false}
width={200}
open={this.props.open}
onRequestChange={this.props.onRequestChange}
>
<MenuItem
primaryText={'Dashboard'}
leftIcon={<DashboardIcon/>}
containerElement={<Link to={'/'}/>}
onClick={this.props.onClick}
/>
</Drawer>
);
}
}
class AppShell extends Component {
constructor(props) {
super(props);
this.state = {
open: false,
drawer : false
};
}
handleDrawerToggle = (e) => {
if (!this.state.drawer) {
this.setState({drawer: true});
e.preventDefault();
} else {
this.setState({open: !this.state.open});
}
}
render() {
const LazySidebarDrawer = this.state.drawer && (<SidebarDrawer
open={this.state.open}
onMounted={() => this.setState({open: true})}
onClick={() => this.setState({open: false})}
onRequestChange={open => this.setState({open: open})}
/>)
return (
<MuiThemeProvider>
<div>
<AppBar
title="Dashboard"
iconClassNameRight="muidocs-icon-navigation-expand-more"
onLeftIconButtonTouchTap={this.handleDrawerToggle}
/>
{LazySidebarDrawer}
<div id="content" style={ContentStyle}>
{React.cloneElement(this.props.children)}
</div>
</div>
</MuiThemeProvider>
);
}
};
export default AppShell;
But i still can access dashboard when i open login page. How is the correct pattern for login page?
Thanks
Your routing is correct, the exact '/' will only render the Dashboard component when the path is '/'. What you're seeing is the dashboard drawer or AppBar component. The dashboard drawer is still there in the login screen because it's always there in the AppShell code and your routes are children of AppShell. A potential solution would be to move that AppBar component to your Dashboard component if you only want it there.
I want to know how I can pass a status from one page to another page for if used in the other way.
My first page Body.js (Which I handle the state):
import React from 'react';
import './Body.css';
import axios from 'axios';
import { Link } from "react-router-dom";
import User from './User';
class Body extends React.Component {
constructor (){
super();
this.state ={
employee:[],
employeeCurrent:[],
}
}
componentDidMount(){
axios.get('http://127.0.0.1:3004/employee').then(
response=>this.setState({employee: response.data})
)
}
getName = () => {
const {employee} = this.state;
return employee.map(name=> <Link className='link' to={`/user/${name.name}`}> <div onClick={()=>this.add(name)} key={name.id} className='item'> <img className='img' src={`https://picsum.photos/${name.name}`}></img> <h1 className='name'> {name.name} </h1></div> </Link>)
}
add = (name) => {
const nam = name;
this.state.employeeCurrent.push(nam)
console.log(this.state.employeeCurrent)
}
render(){
return(
<div className='body'>
{this.getName()}
</div>
)
}
}
export default Body;
My second page which I want to get the state called employeeCurrent:
import React from 'react';
import Header from './Header';
import Body from './Body';
class User extends React.Component {
constructor (props){
super(props);
this.props ={
employeeCurrent:[],
}
}
render(){
return(
<div >
{this.props.employeeCurrent}
</div>
)
}
}
export default User;
I'm using the React Router, it looks like this:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import './App.css';
import Home from './Home';
import User from './User';
const AppRouter = () => (
<Router>
<div className='router'>
<Route exact path="/" component={Home}/>
<Route path="/user/:id" component={User}/>
</div>
</Router>
);
export default AppRouter;
My project is:
Home page, where you have users, obtained from the API, all users have attributes (name, age, city and country). Saved in employeeCurrent variable:
What I want is: grab these attributes from the clicked user and play on the user page:
Someone would can help me PLEASE?????
Like I explained earlier, you need to lift the state up:
AppRouter (holds the state and passes it to children)
class AppRouter extends React.Component {
state = {
employeeCurrent: [],
employee: []
};
componentDidMount() {
axios
.get("http://127.0.0.1:3004/employee")
.then(response => this.setState({ employee: response.data }));
}
add = name => {
this.setState(prevState => {
const copy = prevState.employeeCurrent.slice();
copy.push(name);
return {
employeeCurrent: copy
};
});
};
render() {
return (
<Router>
<div className="router">
<Route
exact
path="/"
render={props => (
<Home
{...props}
add={this.add}
employee={this.state.employee}
currentEmployee={this.state.currentEmployee}
/>
)}
/>
<Route
path="/user/:id"
component={props => (
<User
{...props}
employee={this.state.employee}
currentEmployee={this.state.currentEmployee}
/>
)}
/>
</div>
</Router>
);
}
}
Body and User (receive parent state as props together with updater functions):
class Body extends React.Component {
getName = () => {
const { employee, add } = this.props;
return employee.map(name => (
<Link className="link" to={`/user/${name.name}`}>
{" "}
<div onClick={() => add(name)} key={name.id} className="item">
{" "}
<img
className="img"
src={`https://picsum.photos/${name.name}`}
/>{" "}
<h1 className="name"> {name.name} </h1>
</div>{" "}
</Link>
));
};
render() {
return <div className="body">{this.getName()}</div>;
}
}
class User extends React.Component {
render() {
// you will need to map employeeCurrent somehow
return <div>{this.props.employeeCurrent}</div>;
}
}
I am following this hackernoon guide https://hackernoon.com/animated-page-transitions-with-react-router-4-reacttransitiongroup-and-animated-1ca17bd97a1a in order to apply enter and leave animations to my react components when a route changes. I have obviously adapted the code to fit my site, and have decided not to use Animated but rather just pure CSS. Right now I'm just testing the code with console.log statements, and I noticed that componentWillEnter and componentWillLeave are not being called on route changes. Also, componentWillAppear only gets called once.
Here is the relevant code for each component, including App.js and index.js:
Animated Wrapper:
import React, {Component} from "react";
import styles from '../styles/AnimatedWrapper.css';
const AnimatedWrapper = WrappedComponent =>
class AnimatedWrapper extends Component {
componentWillAppear(cb) {
console.log('componentWillAppear');
cb();
}
componentWillEnter(cb) {
console.log('componentWillEnter');
cb();
}
componentWillLeave(cb) {
console.log('componentWillLeave');
cb();
}
render() {
return (
<div id="animated-wrapper" className={styles.animatedPageWrapper}>
<WrappedComponent {...this.props}/>
</div>
);}
};
export default AnimatedWrapper;
App.js:
import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import TransitionGroup from "react-transition-group/TransitionGroup";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
import Slider from "./components/Slider";
import ComingSoon from "./components/ComingSoon";
const firstChild = props => {
const childrenArray = React.Children.toArray(props.children);
return childrenArray[0] || null;
}
class App extends Component {
render() {
return (
<div className="App">
<Navbar />
<Switch>
<Route
path="/coming-soon"
children={({ match, ...rest }) => (
<TransitionGroup component={firstChild}>
{match && <ComingSoon {...rest} />}
</TransitionGroup>
)}/>
<Route
path="/"
children={({ match, ...rest }) => (
<TransitionGroup component={firstChild}>
{match && <Slider {...rest} />}
</TransitionGroup>
)}/>
</Switch>
<Footer />
</div>
);
}
}
export default App;
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
Slider.js:
import React, { Component } from 'react';
import _ from 'lodash';
// components
import AnimatedWrapper from './AnimatedWrapper';
import Separator from './Separator';
// styles
import styles from '../styles/Slider.css';
// images
import Apartment from "../../public/images/apartment.jpg";
import Floor from "../../public/images/floor.jpg";
import Furniture from "../../public/images/furniture.jpg";
import Kitchen1 from "../../public/images/kitchen.jpg";
import Kitchen2 from "../../public/images/kitchen-2.jpg";
class SliderComponent extends Component {
constructor(props) {
super(props);
this.state = {
currentSlide: 0,
slides: [Apartment, Floor, Furniture, Kitchen1, Kitchen2]
};
}
componentDidMount() {
this.zoomAnimation();
this.slideContentAnimation();
this.sliderInterval = setInterval(() => {
if (this.state.currentSlide === 4) {
if (this.refs.slider) {
this.setState({ currentSlide: 0 });
}
} else {
if (this.refs.slider) {
this.setState({ currentSlide: this.state.currentSlide + 1 });
}
}
}, 6000);
}
componentWillUpdate() {
const currentContent = document.getElementById(`content-${this.state.currentSlide}`);
setTimeout(() => {
currentContent.classList.remove(`${styles.currentContent}`);
}, 1500);
}
componentDidUpdate() {
this.zoomAnimation();
this.slideContentAnimation();
}
setSlide(number) {
this.setState({ currentSlide: number });
}
zoomAnimation() {
setTimeout(() => {
const currentSlide = document.getElementById(`slide-${this.state.currentSlide}`);
currentSlide.classList.add(`${styles.slideZoom}`);
}, 500);
}
slideContentAnimation() {
setTimeout(() => {
const currentContent = document.getElementById(`content-${this.state.currentSlide}`);
if (currentContent) {
currentContent.classList.add(`${styles.currentContent}`);
}
}, 1500);
}
renderSlides() {
return this.state.slides.map((slide, index) => {
const isCurrent = index === this.state.currentSlide;
const slideStyle = {
backgroundImage: `url(${this.state.slides[index]})`
}
return (
<div
id={`slide-${index}`}
key={`slide-${index}`}
className={`
${styles.slide}
${isCurrent ? styles.currentSlide : null}
`}
style={slideStyle}
alt="slide">
<div
id={`content-${index}`}
key={`content-${index}`}
className={`
${styles.content}
`}>
<h1>{`WE SPECIALIZE IN KITCHENS ${index}`}</h1>
<Separator
containerWidth={720}
circleWidth={5}
circleHeight={5}
backgroundColor="#fff"
lineWidth={350}
lineColor="#fff"
/>
<div
className={`${styles['hvr-sweep-to-top']} ${styles.btn}`}>
More Information
</div>
</div>
</div>
);
});
}
renderNavBar() {
return (
<div className={styles.sliderNav}>
{_.range(5).map((index) => {
return (
<div
key={index}
onClick={() => this.setSlide(index)}
className={this.state.currentSlide === index ? styles.current : null}>
</div>
)
})}
</div>
)
}
render() {
return (
<div className={styles.container} ref="slider">
<div className={styles.slidesContainer}>
{this.renderSlides()}
</div>
{this.renderNavBar()}
</div>
);
}
}
const Slider = AnimatedWrapper(SliderComponent);
export default Slider;
ComingSoon.js:
import React from 'react';
import AnimatedWrapper from './AnimatedWrapper';
import styles from '../styles/ComingSoon.css';
const ComingSoonComponent = function() {
return (
<div>
<div className={styles.mainContent}>
<div>
<h1 className={styles.mainTitle}>{`Coming Soon`}</h1>
</div>
</div>
</div>
);
};
const ComingSoon = AnimatedWrapper(ComingSoonComponent);
export default ComingSoon;
Try to Use react-transition-group, it will be help.
You can use it like this Example. As follow main code:
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
const PageFade = (props) => (
<CSSTransition
{...props}
classNames="fadeTranslate"
timeout={1000}
mountOnEnter={true}
unmountOnExit={true}
/>
)
const Layout = ({ children }) => (
<section>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Non existing</Link></li>
</ul>
</nav>
<hr />
{children}
</section>
)
const App = (props) => {
const locationKey = props.location.pathname
return (
<Layout>
<TransitionGroup>
<PageFade key={locationKey}>
<section className="fix-container">
<Switch location={props.location}>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route component={NotFound} />
</Switch>
</section>
</PageFade>
</TransitionGroup>
</Layout>
)
}
const BasicExample = () => (
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
);
render(<BasicExample />, document.getElementById('root'));