简体   繁体   English

响应路由到具有不同 URL 的相同组件

[英]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.它们有一个路由到同一组件的路由,然后该组件读取 URL 末尾的参数并根据值运行不同的搜索。 For example 's' is search schools and 'p' is search people.例如,'s' 是搜索学校,'p' 是搜索人。 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.例如,如果我从“Find Schools”转到“Find Work”,它会留在学校,但如果我要直接转到“Find Work Places”,则它会直接转到那里。 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.当匹配的路由没有改变时, Routerender道具不会重新安装,即即使路由匹配但路由参数不同,它也不会重新渲染。 Instead use the component prop.而是使用component道具。

react-router-dom component react-router-dom 组件

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.当您使用组件(而不是渲染或子组件,如下所示)时,路由器使用 React.createElement 从给定组件创建一个新的 React 元素。 That means if you provide an inline function to the component prop, you would create a new component every render.这意味着如果您为组件 prop 提供内联函数,您将在每次渲染时创建一个新组件。 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).使用内联函数进行内联渲染时,请使用 render 或 children 道具(如下)。

<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.另一种方法是在SearchPage实现componentDidUpdate生命周期函数,以检测路由参数 prop 何时更新并更新 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.类型数据来自 props,因此你不应该将它持久化到组件状态。 Note : Make sure you use react-router Link component it seems you use native a tags注意:确保您使用 react-router Link 组件,它似乎您使用本机 a 标签

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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