Reputation: 8297
rotateRender() {
if(false) {
return(
<TimerPage></TimerPage>
);
} else {
return(
<RepoPage></RepoPage>
);
}
}
I have two components called TimerPage
and RepoPage
.
I created a simple conditional render function as above, but cannot come up with a condition to make it render iteratively after a certain amount of time.
For example, I first want to render RepoPage
and switch to TimerPage
after 5 minutes and then stay in TimerPage
for 15 mins before I switch again to the RepoPage
.
Any way to do this?
Upvotes: 2
Views: 3093
Reputation: 574
Might not be that elegant, but this works
Actually I was thinking that this block might be more elegant than the first one
const FIRST_PAGE = '5_SECONDS';
const SECOND_PAGE = '15_SECONDS';
const FirstComponent = () => (
<div>5 SECONDS</div>
);
const SecondComponent = () => (
<div>15 SECONDS</div>
);
class App extends Component {
state = {
currentPage: FIRST_PAGE
};
componentDidUpdate() {
const {currentPage} = this.state;
const isFirst = currentPage === FIRST_PAGE;
if (isFirst) {
this._showSecondPageDelayed();
} else {
this._showFirstPageDelayed();
}
}
componentDidMount() {
this._showSecondPageDelayed();
};
_showSecondPageDelayed = () => setTimeout(() => {this.setState({currentPage: SECOND_PAGE})}, 5000);
_showFirstPageDelayed = () => setTimeout(() => {this.setState({currentPage: FIRST_PAGE})}, 15000);
render() {
const {currentPage} = this.state;
const isFirst = currentPage === FIRST_PAGE;
const ComponentToRender = isFirst ? FirstComponent : SecondComponent;
return <ComponentToRender/>;
}
}
Upvotes: 1
Reputation: 1512
As stated in the comment section, you can create a higher order component that will cycle through your components based on the state of that component. Use setTimeout to handle the timer logic for the component.
state = {
timer: true
}
componentDidMount = () => {
setInterval(
() => {
this.setState({ timer: !this.state.timer })
}, 30000)
}
render(){
const {timer} = this.state
if(timer){
return <TimerPage />
} else {
return <RepoPage />
}
}
Edit
Changed setTimeout to setInterval so that it will loop every 5 minutes instead of just calling setState once
Upvotes: 1
Reputation: 2307
You could use the new context API to achieve this. The benefit is now I have a configurable, reusable provider to play with throughout my application. Here is a quick demo: https://codesandbox.io/s/k2vvy54r8o
import React, { Component, createContext } from "react";
import { render } from "react-dom";
const ThemeContext = createContext({ alternativeTheme: false });
class ThemeWrapper extends Component {
state = {
alternativeTheme: false
};
themeInterval = null;
componentDidMount() {
this.themeInterval = setInterval(
() =>
this.setState(({ alternativeTheme }) => ({
alternativeTheme: !alternativeTheme
})),
this.props.intervalLength
);
}
componentWillUnmount() {
if (this.themeInterval) {
clearInterval(this.themeInterval);
}
}
render() {
return (
<ThemeContext.Provider value={this.state}>
{this.props.children}
</ThemeContext.Provider>
);
}
}
const App = () => (
<ThemeWrapper intervalLength={2000}>
<ThemeContext.Consumer>
{({ alternativeTheme }) =>
alternativeTheme ? <p>Alternative Theme</p> : <p>Common Theme</p>
}
</ThemeContext.Consumer>
</ThemeWrapper>
);
render(<App />, document.getElementById("root"));
Whatever you do make sure on componentWillUnmount to clear your interval or timeout to avoid a memory leak.
Upvotes: 0