0

Lately, I've been working on a React app that fetches data and pages from an API. Because of this, instead of creating, say, <Index />, <ContactUs />, <AboutUs /> etc. components, I've just placed a <Page /> component in the middle of the page. This is the component class, a bit simplified " ".

class Page extends Component {
    state = {
        content: ''
    }

    componentDidMount () {
        console.log(this.props)
        const component = this;
        fetch(`http://localhost:3001/pages/${this.props.location.pathname}`)
            .then((data) => {
                return data.json();
            }).then((response) => {
                component.setState({ content: response.content });
            })
            .catch((err) => {
                console.error(`An error was thrown! Error message: ${err}`);
            });
    }

    render () {
        return (
            <JsxParser
                components={ {
                    Button,
                    Typography
                } }

                jsx={ this.state.content }
            />
        )
    }
}

Page.propTypes = {
    location: PropTypes.object.isRequired
}

export default Router.withRouter(Page);

However, if I add <Router.Route component={ Page } /> and then, either through a <Link> or this.props.history.push()/replace(), change the current location, the components does not update and always displays the page corresponding to the original URL (the one just after reloading the page, before navigating to other URLs*). I really don't understand why it's not updating, although I also think that I'm probably just making an extraordinarily simple mistake...
ᵃˡˢᵒ ᶦ ˢᵗᵃʳᵗᵉᵈ ᵘˢᶦⁿᵍ ʳᵉᵃᶜᵗ ˡᵉˢˢ ᵗʰᵃⁿ ᵃ ᵐᵒⁿᵗʰ ᵃᵍᵒ ˢᵒ ᵖˡᵉᵃˢᵉ ᵈᵒⁿ'ᵗ ᵇˡᵃᵐᵉ ᵐᵉ

EDIT:
I have tried to add a DidComponentUpdate method to the Page component; however, although the component does get a change in props every time the URL changes, all of the props regarding location (eg. this.props.location.pathname) stay the same.






* note that this is not necessarily the root URL, if the page loaded, for example, on /contacts, <Page /> will always stay there.

Damiano Magrini
  • 460
  • 8
  • 17

2 Answers2

1

Although I didn't manage to directly update the component, I still managed to fire again componentDidMount() by wrapping it into an inline functional component, whicih was the was one that I actually rendered. I used this code

<Router.Route path='/*' component={ function ({ match }) {
    return <Page path={ match.url } />
} } />

Apparently, it was simpler than I thought...

Damiano Magrini
  • 460
  • 8
  • 17
0

I don't know if you forgot to add the path prop to your Route but this answer assumes you did. Check Route.

This is happening because react-router is rendering the same component with a change in props and your component isn't taking care of it. This also means react won't re-mount your component and hence even if there is a change in URL, you can't see a change in display.

You have two ways to tackle this.

  1. Poll for a change in this.props.location.pathname in componentDidUpdate and make a network request when the prop has changed. See Docs.
  2. Use render props method of react-router-dom to return a component with a key. Render props route

    <Route path="/:page" render={props => (
        <Page key={props.location.pathname} {...props} />
    )}/>
    

A change in key forces react to re-mount the component which calls all the lifecycle methods from scratch and so can be used to remount the component in case of URL change.

Sandeep Mishra
  • 123
  • 1
  • 7
  • Thank you for your answer! However, it's still not working... please read the edit I made (I also tried way n. 2, and it still was not working). – Damiano Magrini Sep 11 '18 at 12:44