反应路由器 v4 防止访问页面

react router v4 prevent to access to page

在 React Router v4 文档中,我阅读了有关 Prompt to prevent to leave a page 的内容: Prompt to prevent to leave,但直到现在我还没有发现任何有关阻止访问的内容,例如旧版本中的 willtransitionto

有什么建议吗?

前一段时间一直在研究这个问题,所以,这里是我的例子(我不确定这是否是最好的方法,也许有一些更好的解决方案,但我仍然想分享):

1) 当您阻止访问并知道必须将用户重定向到哪个页面时:

假设您有 Home 页面和 About 页面,并且您想要询问用户确认以防用户尝试访问它。

所以,在这种情况下,我们可以将此逻辑放在 <Route> 组件中的渲染 属性 中,就像这样

render={(props)=>{
          if(confirm('Are you sure you want to see this page?')){
            return <About />
          } else {
            return <Redirect to='/'/>
          }
        }
      }

因此,如果用户单击 OK,它将显示 About 页面,否则会将用户重定向到 Homepage

class App extends React.Component{
  render(){
    return(
    <Router>
      <div className="container">
        <ul>
         <li><Link to="/">Home</Link></li>
         <li><Link to="/about">About</Link></li>
       </ul>
      <hr/>
      <Route exact path="/" component={Home} /> 
      <Route path="/about" render={(props)=>{
              if(confirm('Are you sure you want to see this page?')){
                return <About />
              } else {
                return <Redirect to='/'/>
              }
            }
          }/>
     </div>
    </Router>
    )
  }
}

完整的例子是here

2) 与第一个示例相同,但如果您想将用户重定向回用户尝试访问 About 页面.[= 的同一页面28=]

在这种情况下,为了确保 App 组件获取位置信息,我将其包装如下:

<Router>
    <Route path="/" render={
           (props)=>{
               return <App {...props}/>
           }
    } /> 
</Router>

然后在这里,在主应用程序组件 (App) 中,我们可以跟踪路径,就像这样(因此,每次 App 从 ReactRouter 获取有关位置和内容的新属性组件,我们可以检查它并保存在我们的 state):

  constructor(props){
        super(props);

        this.state={
            prevPath: props.location.pathname
        }
    }

   componentWillReceiveProps(nextProps) {
        if (nextProps.location !== this.props.location) {
          this.setState({ prevPath: this.props.location.pathname })
        }
    }

然后,如果用户想要转到关于页面,我们可以,如果用户未确认重定向,则将他带回上一页,因此,渲染 属性 将如下所示:

 <Route path="/about" render={(props)=>{
                if(confirm('Are you sure you want to see this page?')){
                  return <About />
                } else {
                  let toPath = '/';
                  if(this.state.prevPath){
                    toPath=this.state.prevPath
                  }

                  return <Redirect to={toPath}/>
                }
              }
            }/>

完整示例here