在反应中,在 Render() 之前执行 API 调用和重定向的最佳方法是什么?

In react, what is the best way to perform an API call and redirect before Render()?

我主要做后端,所以我的 javascript 不是全部,但我在设计的管理面板中遇到了问题。网站的某些部分只能由特定用户访问。

每次应加载受保护的组件时,我都会向我的 REST 服务器发送一个请求,该请求 returns 返回 200 或 403,200 响应包含一个名为 redirect 的密钥,它是False。所以我的想法是执行以下操作:

...
import { Redirect } from 'react-router-dom';
import axios from 'axios';


class MyProtectedComponent extends Component {
    constructor(props) {
        super(props);

        this.state = {
            authCalled: false,
            redirect: true,
        };
    }

    componentDidMount() {
        console.log("mounting...")
        axios.get('<https://url>',
        {headers: {"Authorization": localStorage.getItem("token")}})
        .then(res => {
            this.setState({
                redirect: res.data.data.redirect,
                authCalled: true,
            });
        })
    }

    render() {
        if (this.state.authCalled === false) {
           return (
               <div className="animated fadeIn">
               <Row>
               <Col>
               authenticating...
               </Col>
               </Row>
               </div>
           )
       }

       if (this.state.redirect === true) {
           return <Redirect to={{pathname: "/nonauthpage"}} />;
       }

   return ( ....... <main code> ..... )

现在,如果服务器发回允许用户访问的 200,组件将加载,但如果不是,页面将卡在 <authenticating> 阶段,永远不会 Redirects。

我所有的 javascript 都是自学的,如果我正在做的是执行此类事情的坏习惯,请告诉我如何正确地做,或者告诉我为什么会这样不工作所以我让它工作。

您可以按如下方式自定义代码以使其正常工作

....
import { Redirect } from 'react-router-dom';
import axios from 'axios';


class MyProtectedComponent extends Component {
    constructor(props) {
        super(props);

        this.state = {
            authCalled: false,
            redirect: true,
        };
    }

    componentDidMount() {
        console.log("mounting...")
        axios.get('<https://url>',
        {headers: {"Authorization": localStorage.getItem("token")}})
        .then(res => {
            this.setState({
                redirect: res.data.data.redirect,
                authCalled: true,
            });
        }).catch(err => {
            this.setState({
                redirect: true,
                authCalled: true,
            });
        })
    }

    render() {
        if (this.state.authCalled === true) {
            if (this.state.redirect === true) { 
                return <Redirect to={{pathname: "/nonauthpage"}} />;
            } else {
                  return ( ....... <main code> ..... ) 
            }
        }
        else {
            return (
                <div className="animated fadeIn">
                    <Row>
                        <Col>
                        authenticating...
                        </Col>
                    </Row>
                </div>
            )
        }
    }
}

您正在使用 axios,这意味着如果响应不是 200(或 2XX),then 将不会被执行,您需要像下面这样链式执行 .catch

componentDidMount() {
    console.log("mounting...")
    axios.get('<https://url>',
    {headers: {"Authorization": localStorage.getItem("token")}})
    .then(res => {
        this.setState({
            redirect: res.data.data.redirect,
            authCalled: true,
        });
    }).catch(error => {
        // You can do additional checks here like e.g. check if the response code is 403 or 401 
        this.setState({
             redirect: true,
             authCalled: true
        });
    })
}