6

I am very new to React so apologies if this is just a duplicate - I have tried to look at solution to other questions but none have helped me.

I want a React component to re-render when the query string of the page changes. I have a basic contact form and I'm pre-populating a single field with a value passed via the query string. My understanding is that React should re-render a component whenever it's state or components change and seeing as the query string is part of the props (this.) then I thought it would be easy, but this does not seem to be the case for me.

Route

<Route exact path="/contact-us" component={ContactUs} />

Component

import React, { PureComponent, Fragment } from 'react';
import bannerImage from './../../assets/images/contact-banner.jpg';
import QueryString from 'query-string';

class ContactUs extends PureComponent {
  render() {
    return (
      <Fragment>
        <CommonBanner banner={bannerImage} title="Contact us" />
        <ContactUsForm tripName={QueryString.parse(this.props.location.search).tripName)} />
      </Fragment>
    );
  }
}

export default ContactUs;

I want the contact form to re-render when: The user has clicked through from a location which send the trip name through via the query string and then clicks the 'Contact Us' button in the header of the page which links to the Contact Us page again, but without the trip name in the query string. This should then remove the pre-population of the trip name field.

UPDATE

I've noticed that if I manually removed the query string from the URL in the browser then the field is blanked out as expected. It's only when I click a link in the menu that just links to 'contact-us' that nothing seems to happen.

5
  • This question will help you out stackoverflow.com/questions/48993247/… Commented Jun 27, 2018 at 10:30
  • Yeah, I saw your answer there before. I'd rather not mess with the router and just have a solution for this one component if possible. Commented Jun 27, 2018 at 10:40
  • Well, we aren't messing with the router, you can choose to use your custom withRouter or the default one based on your requirement and also, this is a generic enough solution that you can use throughout your app Commented Jun 27, 2018 at 10:41
  • But how come the component doesn't re-render even though the props are changing? Commented Jun 27, 2018 at 11:12
  • this.props.location.search has changed... Commented Jun 27, 2018 at 11:42

2 Answers 2

0

Figured it out. This was not causd by the ContactUs component after all. It was caused by the sub-component ContactUsForm which is using Formik and setting the initial values like so:

<Formik
  initialValues={{
  firstName: '',
  surName: '',
  email: '',
  message: '',
  tripName: this.props.tripName || '',
}}
...
>

You need to allow Formik to reinitialize the form if initial values changes using enableReinitialize - https://github.com/jaredpalmer/formik#enablereinitialize-boolean

<Formik
  initialValues={{
  firstName: '',
  surName: '',
  email: '',
  message: '',
  tripName: this.props.tripName || '',
}}
enableReinitialize={true}
...
>
Sign up to request clarification or add additional context in comments.

Comments

-1
componentDidUpdate(prevProps, prevState) {
  if (prevProps.match.params.'queryVariable' !== this.props.match.params.'queryVariable') {
  //either 
    this.forceUpdate()
 //or
    this.setState({
      something:something
    })
  }
}

put your query param variable example prevProps.match.params.id and this.props.match.params.id

2 Comments

This doesn't seem to work either. It calls forceUpdate but nothing happens still.
Query params is different to url params. Query params are the one after ?, like ?param1=value1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.