简体   繁体   English

如何从 ReactJS 的提取中设置 state?

[英]How do I set state from within a fetch in ReactJS?

I have the following component class:我有以下组件 class:

import React, { Component } from "react";
import Form from "react-bootstrap/Form";
import Button from 'react-bootstrap/Button'
import './login.css';

export default class Login extends Component {

    handleSubmit = (e) => {

        var myRes = null;

        fetch(
            "/exist/apps/my-app/modules/who-am-i.xq?user=emh&password=emh",
            {
            }
        )
          .then((response) => response.json())
          .then(
            (result) => {
                myRes = {
                    error: null,
                    loaded: true,
                    user: result
                };
            },
            // Note: it's important to handle errors here
            // instead of a catch() block so that we don't swallow
            // exceptions from actual bugs in components.
            (error) => {
                myRes = {
                    error: error,
                    loaded: true,
                    user: {}
                };
            }
          );
        this.setState(myRes);
    }

    render() {
        return (
      <div className="auth-wrapper">
        <div className="auth-inner">
            <Form onSubmit={this.handleSubmit}>
                <h3>Sign In</h3>
.
.
.
                <Button variant="primary" type="submit">Submit</Button>
            </Form>
            </div>
            </div>
        );
    }
}

I have searched for the answer, but what I got was in (result) => {this.setState({error: null, loaded: true, user: result})} .我已经搜索了答案,但我得到的是(result) => {this.setState({error: null, loaded: true, user: result})} Unfortunately the this is undefined within the fetch.不幸的是, this在 fetch 中是未定义的。

I want to in the result and error to set the value in state.我想在结果和错误中设置 state 中的值。 Unfortunately the this is not defined within the fetch result.不幸的是,这没有在获取结果中定义。 How do I set the state in Login from within the fetch?如何从 fetch 中在Login中设置 state?

The problem is you're calling setState too soon.问题是你调用setState太快了。 You need to call it only when your promise has settled.只有在您的 promise 安顿下来后,您才需要调用它。 The easiest way to do that is with a subsequent then , see *** comments:最简单的方法是使用随后的then ,请参阅***评论:

handleSubmit = (e) => {
    // *** No `let myRes` here
    fetch(
         "/exist/apps/my-app/modules/who-am-i.xq?user=emh&password=emh",
         {
         }
     )
       .then((response) => response.json())
       .then(
         (result) => {
             // *** Transform the resolution value slightly
             return {
                 error: null,
                 loaded: true,
                 user: result
             };
         },
         // Note: it's important to handle errors here
         // instead of a catch() block so that we don't swallow
         // exceptions from actual bugs in components.
         (error) => {
             // *** Turn rejection into resolution by returning
             // a replacement for `myRes`.
             return {
                 error: error,
                 loaded: true,
                 user: {}
             };
         }
       )
       .then(myRes => {
         // *** You always end up here because both fulfillment and rejecction
         // result in an object that's used to fulfill the promise
         // created by the first call to `then`
         this.setState(myRes);
       })
       // *** Still use a final handler to catch errors from
       // fulfillment handlers
       .catch(error => {
         // Handle/report error
       });
};

first of all fetch should always be async second put const that = this;首先 fetch 应该始终是 async 第二个 put const that = this; in the top of the handler and then you can do setState like this:在处理程序的顶部,然后您可以像这样执行 setState:

handleSubmit = (e) => {
        const self = this
        var myRes = null;

        fetch(
            "/exist/apps/my-app/modules/who-am-i.xq?user=emh&password=emh",
            {
            }
        )
          .then((response) => response.json())
          .then(
           result => {
                self.setState({error: null, loaded: true, user: result})
                myRes = {
                    error: null,
                    loaded: true,
                    user: result
                };
            },
            // Note: it's important to handle errors here
            // instead of a catch() block so that we don't swallow
            // exceptions from actual bugs in components.
            (error) => {
                myRes = {
                    error: error,
                    loaded: true,
                    user: {}
                };
            }
          );
    }

and advise you to create a file for the fetch like this:并建议您为 fetch 创建一个文件,如下所示:

 const nameYouDecided = async () -> {
    await fetch("/exist/apps/my-app/modules/who-am-i.xq?user=emh&password=emh" )
          .then((response) => response.json())
    }

and then when you call it in your code it is shorter In addition if you have a couple of get request you should do the following in different file like get.js然后当您在代码中调用它时,它会更短此外,如果您有几个获取请求,您应该在不同的文件中执行以下操作,例如 get.js

    const get = async (url) => (
        await fetch(url)
            .then(response => response.json())
            .then(json => json
            )
    );
const nameYouDecided = get("/exist/apps/my-app/modules/who-am-i.xq?user=emh&password=emh")

You need to set the state inside of.then() fetch function.您需要在 of.then() fetch function 中设置 state。

Fetch need time to fetch urls, setstate doesnt wait this time so it set a Promise. Fetch 需要时间来获取 url,setstate 这次不会等待,所以它设置了一个 Promise。 To turn around this, you need to put your setState inside a.then, the setState line will only be executed when your fetch done the job要解决这个问题,您需要将 setState 放在 a.then 中,setState 行只会在您的 fetch 完成工作时执行

fetch(
  "/exist/apps/my-app/modules/who-am-i.xq?user=emh&password=emh",
  {
  }
)
.then((response) => response.json())
.then(
  (result) => {
      return {
          error: null,
          loaded: true,
          user: result
      };
  },

  (error) => {
      return {
          error: error,
          loaded: true,
          user: {}
      };
  }
).then(myRes => {
  this.setState(myRes); 
});
}

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

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