Search code examples
javascriptreactjsrenderingreact-propsreact-state-management

React Rendered page is 1 page behind requested page


I have a state in Redux called page and is changed whenever I click a URL to another page. This is to make my website just have one URL. Whenever I request for a new page, it only gets updated on the next click. For example, when I click Login, nothing happens. Then when I click Register, the Login page renders. Then when I click About, the Register page renders. Why is the page rendering 1 page slow? Is there any way to fix this? I want to make a fade animation to the page and then make the new page appear. Is this something to do with having to use nextProps? I've heard about it somewhere but I neither know what it is nor know how to use it.

import React, { Component } from 'react'

// Redux
import { connect } from "react-redux"

// Components
import Login from './routes/Login'
import About from './routes/About'
import Register from './routes/Register'
import Chat from './routes/Chat'

// PropTypes
import PropTypes from 'prop-types'

class Renderer extends Component {
    state = {
        rendered: <About /> // Default page to render
    }

    static propTypes = {
        page: PropTypes.string.isRequired
    }

    componentDidUpdate(prevProps) {
        const main = document.getElementsByTagName('main')[0] // Where the rendered page should be

        if (this.props.page !== prevProps.page) { // If page state changes

            main.style.animation = "fadeOut 0.5s forwards" // Fade old page
            setTimeout(() => { // After faded
                let returned

                switch (this.props.page) {
                    case 'About':
                        returned = <About />
                        break
                    case 'Login':
                        returned = <Login />
                        break
                    case 'Register':
                        returned = <Register />
                        break
                    case 'Chat':
                        returned = <Chat />
                        break
                    default:
                        returned = <About />
                }

                this.state.rendered = returned
                main.style.animation = "fadeIn 0.5s forwards" // Show new page
            }, 500)

        }
    }

    render() {
        return this.state.rendered
    }
}

const mapStateToProps = state => ({
    page: state.page
})

export default connect(mapStateToProps)(Renderer)

Is there a way to render data in the componentDidUpdate() instead of putting it in the state then updating it? Because I think that is the main cause of the problem


Solution

  • I'm guessing that you should call this.setState and not this.state.rendered = returned. Furthermore the animation isn't going to be right this way. I think it works if you call the animation inside the setState callback, which should happen after the component is re-rendered ( see reactjs.org/docs/react-component.html#setstate )