如何在ReactJS的提取中设置状态?

问题描述

我有以下组件类:

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,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>
        );
    }
}

我已经搜索了答案,但是得到的却是(result) => {this.setState({error: null,user: result})}。不幸的是,this提取中未定义。

我想在结果和错误中将值设置为状态。不幸的是,这未在获取结果中定义。如何从获取中设置Login中的状态?

解决方法

问题是您打电话给setState太早了。仅在您的诺言履行后,您才需要调用它。最简单的方法是使用后续的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,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
       });
};
,

首先应始终异步 第二,将const that = 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,user: result})
                myRes = {
                    error: null,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,user: {}
                };
            }
          );
    }

,并建议您为提取创建文件,如下所示:

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

,然后当您在代码中调用它时,它会更短 另外,如果您有几个获取请求,则应执行以下操作 在类似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")
,

您需要在.then()获取函数内部设置状态。

获取需要一些时间来获取url,setstate这次不等待,因此它设置了Promise。要解决此问题,您需要将setState放在一个.then中,然后setState行仅在获取完成工作后才会执行

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