简体   繁体   中英

React Routing to Same Component with Different URL

In my main class I have a nav bar with the options below:

          <NavDropdown title="Search" id="collasible-nav-dropdown">
            <NavDropdown.Item href="#/searchpage/p" onClick={this.dontEdit}>Find People</NavDropdown.Item>
            <NavDropdown.Item href="#/searchpage/s" onClick={this.searchSchool}>Find Schools</NavDropdown.Item>
            <NavDropdown.Item href="#/searchpage/w" onClick={this.dontEdit}>Find Work Places</NavDropdown.Item>
          </NavDropdown>

These have a route which routes to the same component which then reads the parameter at the end of the URL and runs a different search depending on the value. For example 's' is search schools and 'p' is search people. If I navigate between the different search functions from the nav bar then it doesn't refresh to the new search. For example if I go from 'Find Schools' to 'Find Work' it stays on schools, but if I were to go direct to 'Find Work Places' then it goes there direct. Also if I navigate to the home page and back to another search then it works.

The route looks like:

<Route path="/searchpage/:type"  render={props => (<SearchPage {...props} findPerson={this.findPerson} routeReset={this.routeReset} getPersonsByName={this.getPersonsByName} />)}/>

Is anyone able to advise how to get this to route as I want it to? The search component is like:

import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Container from 'react-bootstrap/Container';
import Button from 'react-bootstrap/Button';

import Flash from './components/flash';
import Search from "./components/search";

const searchtypes = {"p":"People","w":"Work Places","s":"Schools"};

class SearchPage extends Component {



  constructor(props) {
    super(props);

    this.state = {
      type:this.props.match.params.type
    }
  }

  componentDidMount(){

  }


  render() {
    return (
      <Container>
        <Row>
          <Col>
            <h4>Search {searchtypes[this.state.type]}</h4>
            <br/>
          </Col>
        </Row>
        <Row><Col><Search {...this.props} type={this.state.type}/></Col></Row>
      </Container>
    );
  }
}

export default SearchPage;

The Route 's render prop doesn't remount when the matched route doesn't change, ie even when the route matches but the route param is different it won't re-render. Instead use the component prop.

react-router-dom component

When you use component (instead of render or children, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop (below).

<Route
  path="/searchpage/:type"
  component={props => (
    <SearchPage
      {...props}
      findPerson={this.findPerson}
      routeReset={this.routeReset}
      getPersonsByName={this.getPersonsByName}
    />
  )}
/>

An alternative to this is to implement the componentDidUpdate lifecycle function in SearchPage to detect when the route param prop updates and update the type stored in state. This way the component won't continually unmount/mount each time.

componentDidUpdate(prevProps) {
  if (prevProps.match.params.type !== this.props.match.params.type) {
    setState({
      type: this.props.match.params.type,
    });
  }
}

Try this:

class SearchPage extends Component {

  render() {
    return (
      <Container>
        <Row>
          <Col>
            <h4>Search {searchtypes[this.props.match.params.type]}</h4>
            <br/>
          </Col>
        </Row>
        <Row><Col><Search {...this.props} type={this.props.match.params.type}/></Col></Row>
      </Container>
    );
  }
}

The type data comes from props and therefore you should not persist it on the component state. Note : Make sure you use react-router Link component it seems you use native a tags

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM