Javascript 根据URL更新页面内容,不要重新加载整个页面 上下文

Javascript 根据URL更新页面内容,不要重新加载整个页面 上下文,javascript,reactjs,react-router,Javascript,Reactjs,React Router,我正在使用路由器4 我有以下基本路由器 <Router> <Route exact path="/" component={HomePage} /> <Route path="/courses/:courseName" render={(props) => { switch (props.match.params) { case '1': return Rea

我正在使用路由器4

我有以下基本路由器

<Router>
    <Route exact path="/" component={HomePage} />
    <Route
      path="/courses/:courseName"
      render={(props) => {
        switch (props.match.params) { 
          case '1':
            return React.createElement(
              fetch('courses/1/')(CoursePage),
              props,
              null
            );
          case '2':
            return React.createElement(
              fetch('courses/2/')(CoursePage),
              props,
              null
            );
          default:
            return <FourOFour />
        }
      }}
    />
</Router>
this.determinivesiblessection(sectionName,data)
只需将
数据
传递给相应的组件,以便基于
sectionName
进行渲染,然后返回它

这样做的问题是,当单击一个部分时,整个页面将再次加载

我的意思是,再次启动
fetch('courses/NUMBER/')(CoursePage)
,我们在等待数据返回的同时获得加载屏幕,最后显示页面,显示我们现在单击的部分以及下面的正确内容

我想我明白为什么会这样。由于URL发生了更改,所有
路由器
组件都会收到更改通知,它们的
路由
组件也会收到更改通知,因此,由于在基本
路由器
中,要呈现的组件基本上每次都是新的,即使我们在同一页面上,因为
fetch()
返回了一个新的组件,因此页面被“重新加载”

问题 有没有办法防止这种行为?这意味着,所选部分对URL的更改不会影响整个页面。仅影响当前课程页面内容

我想出的一个办法似乎是:

我像这样重写了我的基本
路由器

<Router>
  <Page>
    <Route exact path="/" component={HomePage} />
    <Route path="/courses/:courseName" component={CoursePages} />
  </Page>
</Router>
这整件事的关键是
shouldComponentUpdate
以及我在
LoggedIn
组件中有第二个
,因为第二个
将强制其内容重新呈现,即使父组件没有重新呈现(因为
shouldComponentUpdate


有没有更好的方法来解决我缺少的问题?

我认为将区段路线放在
LoggedIn
组件中更好。因为它更适合用路由器v4来处理这种情况(参见文档)

首先,将基本路由器保持在第一个代码块中。根据给出的解释,我假设您的CoursePage组件或多或少是这样的

class CoursePage extends Component{

  //...

  render(){
    return this.props.IsLoggedIn ? <LoggedIn/> : <LoggedOut/>
  }
}
class CoursePage扩展组件{
//...
render(){
返回此.props.IsLoggedIn?:
}
}
现在,在LoggedIn组件中为不同的部分设置路由,如下所示

import React, { Component } from 'react';
import {
  Switch
  Route,
  Redirect
} from 'react-router-dom'

class LoggedIn extends Component{

  // ...

  render(){
    const { match } = this.props;
    return (
      <Switch>
        {/* This will redirect /courses/:courseName to /courses/:courseName/overview */}
        <Redirect exact from={`${match.url}/`} to={`${match.url}/overview`}/>
        <Route path={`${match.url}/overview`} component={Overview}/>
        <Route path={`${match.url}/contents`} component={Contents}/>
        <Route path={`${match.url}/reviews`} component={Reviews}/>
      </Switch>
    );
  }
}
import React,{Component}来自'React';
进口{
转换
路线,,
重新使用
}从“反应路由器dom”
类LoggedIn扩展了组件{
// ...
render(){
const{match}=this.props;
返回(
{/*这将把/courses/:courseName重定向到/courses/:courseName/overview*/}
);
}
}
可能需要向该呈现方法添加更多组件或HTML标记,使其看起来像带有标题的选项卡


由于部分路由在CoursePage呈现之后呈现,因此当您导航到同一课程中的不同部分时,它不会再次获取数据。

不幸的是,这仍然会导致在URL更改时从服务器获取数据。我想这是因为,引用我的问题,“在基本路由器中,每次渲染的组件基本上都是新的”。此外,即使要加载的URL类似于
/courses/:coursename/reviews,也会重定向到
/overview
。是的,刚刚意识到基本路由器中仍然存在问题。但我不确定为什么即使使用
exact
也不能工作。
class CoursePage extends Component{

  //...

  render(){
    return this.props.IsLoggedIn ? <LoggedIn/> : <LoggedOut/>
  }
}
import React, { Component } from 'react';
import {
  Switch
  Route,
  Redirect
} from 'react-router-dom'

class LoggedIn extends Component{

  // ...

  render(){
    const { match } = this.props;
    return (
      <Switch>
        {/* This will redirect /courses/:courseName to /courses/:courseName/overview */}
        <Redirect exact from={`${match.url}/`} to={`${match.url}/overview`}/>
        <Route path={`${match.url}/overview`} component={Overview}/>
        <Route path={`${match.url}/contents`} component={Contents}/>
        <Route path={`${match.url}/reviews`} component={Reviews}/>
      </Switch>
    );
  }
}