简体   繁体   English

为什么我在 React 中的 fetch function(和构造函数)被调用了两次?

[英]Why is my fetch function (and Constructor) in React being called twice?

EDIT: Changed the title since I removed <React.StrictMode> from my index.ts and now the constructor and the fetch function inside it get called twice.编辑:更改了标题,因为我从 index.ts 中删除了 <React.StrictMode> ,现在构造函数和其中的 fetch function 被调用了两次。

I am creating a URL Shortner Service, and I am stuck on the bit where a user visits the frontend URL with the hash code and then is redirected to the original URL. I am creating a URL Shortner Service, and I am stuck on the bit where a user visits the frontend URL with the hash code and then is redirected to the original URL. I am doing this project mostly in Typescript.我主要在 Typescript 中做这个项目。

I am using Node JS and Express as my Backend with Mongo as my DB.我使用 Node JS 和 Express 作为我的后端,使用 Mongo 作为我的数据库。 It is running on port 3001.它在端口 3001 上运行。

I am using React, React-Router, and Redux for my frontend.我在前端使用 React、React-Router 和 Redux。 It is running on port 3000.它在端口 3000 上运行。

So my Routes.js file looks like this所以我的 Routes.js 文件看起来像这样

import React from "react";
import {BrowserRouter as Router, Route, Switch, Redirect} from "react-router-dom";
import Rerouting from "../pages/Rerouting/Rerouting"


const Routes = () => (
    <Router>
        <Switch>

            <Route
                path="/:urlCode"
                exact={true}
                component={Rerouting}
            />

        </Switch>
    </Router>
);

My Rerouting.tsx file looks like this我的 Rerouting.tsx 文件看起来像这样

import React from 'react';
import { connect } from "react-redux";
import BackendHandler from "../../BackendHandler";


class Rerouting extends React.Component {

    constructor(props) {
        super(props)
        BackendHandler.fetch(BackendHandler.REROUTE, props.match.params.urlCode);
    }

    render() {
        const originalUrlFromBackend = this.props["backend"].map((item: { originalUrl: string; }) => item.originalUrl)
        return (
            window.location.href = originalUrlFromBackend 
            )
    }

}

function mapStateToProps(state) {
    return {
        backend: state.backend.urlData,
    }
}

export default connect(mapStateToProps)(Rerouting);

The relevant parts of my BackendHandler.ts file look like this我的 BackendHandler.ts 文件的相关部分如下所示

import store from './redux/store/index';
import {
    backendRequestFailed,
    backendRequestSent,
    backendRequestSucceeded
} from "./redux/actions/fetchFromBackendActions";


class BackendHandler {
    static URL: string;
    static REROUTE: string;
    static fetch(path, params, data = null, init = {}) {
        store.dispatch(backendRequestSent());

        const path_with_params: string = path + params
        fetch(path_with_params, {
            ...init,
            method: "GET",
            body: data,
            credentials: "same-origin",
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(BackendHandler._fulfillFetchHandler, BackendHandler._rejectHandler);
    }

    static _fulfillFetchHandler(response) {
        switch (response.status) {
            case 200:
                response.json().then(BackendHandler._jsonToStore) 
            default:
                store.dispatch(backendRequestFailed())
        }
    }

    static _rejectHandler(error) {
        store.dispatch(backendRequestFailed())
    }

    static _jsonToStore(json) {
        store.dispatch(backendRequestSucceeded(json));
    }

}

BackendHandler.REROUTE = "http://localhost:3001/"

export default BackendHandler;

The problem I am facing right now is that when I visit the frontend URL with a hash code (eg - HTTP://localhost:3000/lol), I see this in my console我现在面临的问题是,当我使用 hash 代码访问前端 URL 时(例如 - HTTP://localhost:3000/ 在我的控制台中) 控制台输出

and I see this in my Redux state我在我的 Redux state 中看到了这个Redux 商店

As you can see, my urlData does exist, and here is a closer look at it.如您所见,我的urlData确实存在,这里仔细看一下。 网址数据

This means my backend is working fine and sending the response.这意味着我的后端工作正常并发送响应。 But then the last error I see is但是我看到的最后一个错误是类型错误

This is probably because, by the time this.props.backend is called, the backend state has not updated.这可能是因为在调用 this.props.backend 时,后端 state 尚未更新。 So how do I get out of this error hell and fix it?那么我该如何摆脱这个错误地狱并修复它呢?

You should call asynchronous tasks oncomponentDidMount() method.您应该在componentDidMount()方法上调用异步任务。 Once the promise gets fulfilled the redux store will dispatch the event for reloading a connected component with the new props.一旦 promise 得到满足,redux 存储将调度事件以使用新道具重新加载连接的组件。

Documentation says literally文档字面意思是

componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). componentDidMount() 在组件安装后立即调用(插入到树中)。 Initialization that requires DOM nodes should go here.需要 DOM 节点的初始化应该在这里 go。 If you need to load data from a remote endpoint, this is a good place to instantiate the network request.如果您需要从远程端点加载数据,这是实例化网络请求的好地方。

There is also no need for creating a React.Component just for making an async call to a remote server.也不需要仅仅为了对远程服务器进行异步调用而创建React.Component The render method of a component should returns a ReactNode = HTML code.组件的渲染方法应该返回一个ReactNode = HTML代码。 You need also to verify that your backend prop is not undefined您还需要验证您的backend道具是否undefined

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM