首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用react-router-v4进行异步身份验证

使用react-router-v4进行异步身份验证
EN

Stack Overflow用户
提问于 2017-09-12 02:36:04
回答 3查看 7.2K关注 0票数 17
代码语言:javascript
复制
const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    isAuthenticated ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

我想将isAuthenticated更改为aysnc请求isAuthenticated()。但是,在响应返回页面重定向之前。

为了清楚起见,isAuthenticated函数已经设置好了。

EN

回答 3

Stack Overflow用户

发布于 2017-09-12 02:54:08

如果您没有使用Redux或任何其他类型的状态管理模式,则可以使用Redirect组件和组件状态来确定是否应该呈现页面。这将包括将状态设置为加载状态、进行异步调用、在请求已完成保存用户之后、或者缺少用户来声明和呈现Redirect组件,如果不满足标准,则组件将重定向。

代码语言:javascript
复制
class PrivateRoute extends React.Component {
  state = {
    loading: true,
    isAuthenticated: false,
  }
  componentDidMount() {
    asyncCall().then((isAuthenticated) => {
      this.setState({
        loading: false,
        isAuthenticated,
      });
    });
  }
  render() {
    const { component: Component, ...rest } = this.props;
    if (this.state.loading) {
      return <div>LOADING</div>;
    } else {
      return (
        <Route {...rest} render={props => (
          <div>
            {!this.state.isAuthenticated && <Redirect to={{ pathname: '/login', state: { from: this.props.location } }} />}
            <Component {...this.props} />
          </div>
          )}
        />
      )
    }
  }
}
票数 17
EN

Stack Overflow用户

发布于 2020-04-14 09:03:12

如果有人对使用钩子而不是类组件实现@CraigMyles感兴趣:

代码语言:javascript
复制
export const PrivateRoute = (props) => {
    const [loading, setLoading] = useState(true);
    const [isAuthenticated, setIsAuthenticated] = useState(false);

    const { component: Component, ...rest } = props;

    useEffect(() => {
        const fetchData = async () => {
            const result = await asynCall();

            setIsAuthenticated(result);
            setLoading(false);
        };
        fetchData();
    }, []);

    return (
        <Route
            {...rest}
            render={() =>
                isAuthenticated ? (
                    <Component {...props} />
                ) : loading ? (
                    <div>LOADING...</div>
                ) : (
                    <Redirect
                        to={{
                            pathname: "/login",
                            state: { from: props.location },
                        }}
                    />
                )
            }
        />
    );
};

它在使用以下命令调用时效果很好:

代码语言:javascript
复制
<PrivateRoute path="/routeA" component={ComponentA} />
<PrivateRoute path="/routeB" component={ComponentB} />
票数 11
EN

Stack Overflow用户

发布于 2018-05-14 12:30:38

@pizza r0b的解决方案对我来说非常有效。然而,我不得不稍微修改一下解决方案,以防止加载div被多次显示(应用程序中定义的每个PrivateRoute都显示一次),方法是将加载div呈现在路由内部而不是路由外部(类似于React Router's auth example):

代码语言:javascript
复制
class PrivateRoute extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      loading: true,
      isAuthenticated: false
    }
  }

  componentDidMount() {
    asyncCall().then((isAuthenticated) => {
      this.setState({
        loading: false,
        isAuthenticated
      })
    })
  }

  render() {
    const { component: Component, ...rest } = this.props
    return (
      <Route
        {...rest}
        render={props =>
          this.state.isAuthenticated ? (
            <Component {...props} />
          ) : (
              this.state.loading ? (
                <div>LOADING</div>
              ) : (
                  <Redirect to={{ pathname: '/login', state: { from: this.props.location } }} />
                )
            )
        }
      />
    )
  }
}

从我的App.js中摘录一段完整的代码:

代码语言:javascript
复制
<DashboardLayout>
  <PrivateRoute exact path="/status" component={Status} />
  <PrivateRoute exact path="/account" component={Account} />
</DashboardLayout>
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46162278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档