Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React Router v4:导航更改时发送请求_Javascript_Reactjs_React Router_React Router V4 - Fatal编程技术网

Javascript React Router v4:导航更改时发送请求

Javascript React Router v4:导航更改时发送请求,javascript,reactjs,react-router,react-router-v4,Javascript,Reactjs,React Router,React Router V4,我正在使用react router v4编写身份验证代码,并使用PrivateRoute和渲染道具,如文档: 我试图做的是:每当用户导航到某个路由时,我都要发送一个操作,向后端发出请求,以验证他是否已登录 像这样: // App.js class App extends Component { checkAuth = () => { const { dispatch, } = this.props; // callback to dispatch } rend

我正在使用react router v4编写身份验证代码,并使用PrivateRoute和渲染道具,如文档:

我试图做的是:每当用户导航到某个路由时,我都要发送一个操作,向后端发出请求,以验证他是否已登录

像这样:

// App.js
class App extends Component {
  checkAuth = () => {
    const { dispatch, } = this.props;
    // callback to dispatch
  }

  render() {
    const props = this.props;

    return (
      <Router>
        <div className="App">
          <Switch>
            <Route exact path="/" component={Login} />

            <PrivateRoute
              exact
              path="/dashboard"
              component={Dashboard}
              checkIsLoggedIn={this.checkAuth}
            />

            {/* ... other private routes here */}

          </Switch>
        </div>
      </Router>
    );
  }
//App.js
类应用程序扩展组件{
checkAuth=()=>{
const{dispatch,}=this.props;
//回拨
}
render(){
const props=this.props;
返回(
{/*…此处的其他专用路由*/}
);
}
在PrivateRoute.js中,我正在监听路由以检查它是否更改,但是当路由更改时,此函数被调用的次数太多,而这是一个调度操作以发出请求的问题

// PrivateRoute.js
const PrivateRoute = ({ component: Component, auth, checkIsLoggedIn, ...rest }) => (
  <Route
    {...rest}
    render={props => {
      props.history.listen((location, action) => {

        if (checkIsLoggedIn) {
          // Here I check if the route changed, but it render too many times to make a request
          checkIsLoggedIn(); // here is the callback props
        }
      });

      if (auth.login.isLoggedIn) {
        return <Component {...props} />;
      } else {
        return <Redirect to={{ pathname: "/login", state: { from: props.location } }} />
      }


    }
    }
  />
);  
//privaterout.js
const privaterout=({component:component,auth,checkIsLoggedIn,…rest})=>(
{
道具。历史。聆听((位置、动作)=>{
如果(选中IsLoggedin){
//在这里,我检查路由是否已更改,但它呈现的次数太多,无法发出请求
checkIsLoggedIn();//这是回调道具
}
});
if(auth.login.isLoggedIn){
返回;
}否则{
返回
}
}
}
/>
);  
我需要一个帮助来找出一个在路由改变时调用后端的好方法。

创建一个是一个非常干净的方法。这样,您就不需要创建单独的
PrivateRoute
组件,只需一行更改即可将任何组件从public转换为protected,反之亦然

像这样的方法应该会奏效:

import React from 'react';
import { Redirect } from "react-router-dom";

export function withAuth(WrappedComponent) {
    return class extends React.Component {
        constructor(props) {
            super(props);

            this.state = {
                isUserLoggedIn: false,
                isLoading: true
            };
        }

        componentDidMount() {
            // Check for authentication when the component is mounted
            this.checkAuthentication();
        }

        checkAuthentication() {
            // Put some logic here to check authentication
            // You can make a server call if you wish,
            // but it will be faster if you read the logged-in state
            // from cookies or something.
            // Making a server call before every protected component,
            // will be very expensive, and will be a poor user experience.
            this.setState({
                isUserLoggedIn: true,       // Set to true or false depending upon the result of your auth check logic
                isLoading: false
            });
        }

        render() {
            // Optionally, you can add logic here to show a common loading animation,
            // or anything really, while the component checks for auth status.
            // You can also return null, if you don't want any special handling here.
            if (this.state.isLoading) return (<LoadingAnimation />);

            // This part will load your component if user is logged in,
            // else it will redirect to the login route
            if (this.state.isUserLoggedIn) {
                return <WrappedComponent authData={this.state} {...this.props} />;
            } else {
                return <Redirect to={{ pathname: "/login", state: { from: props.location } }} />;
            }
        }
    }
}
在您的
应用程序中
,您可以使用一个简单的
路由
组件:

<Route exact path='/dashboard' component={Dashboard} />

您的
应用程序
不需要关心哪些路由受保护,哪些路由不受保护。事实上,只有实际的组件需要知道它们受到了保护


希望这有帮助。干杯!:)

您可以在仪表板的方法
componentDidMount
中向后端发出请求component@ArnoldGandarillas但是我想在用户导航的每个私有路由中发出请求,
privaterout
是一个自定义的React组件。这与反应路由器无关。将其更改为有状态类,并在其
componentDidMount
方法中添加身份验证调用。@FisNaN我应该使用render props或HoC将其更改为类吗?HoC检查has perm是否是一个好方法使用HoC是一个很酷的主意,但我试图避免使用HoC,因为存在一个巨大的问题:如果我使用另一个HoC,它在“withAuth”中有一个同名的道具,那么它将发生冲突!由于道具冲突,我仍然不知道使用HoC是否是一个好主意。我认为与从
应用程序
组件中抽象出auth逻辑所带来的好处相比,这是一个相对较小的问题。您可以将
authData
道具重命名为模糊的名称,或者有意识地确保受保护组件中没有道具冲突。否则,如果您觉得您的
仪表板
或其他组件不需要使用
authData
,您甚至可以选择根本不传递它。
<Route exact path='/dashboard' component={Dashboard} />