POST请求后,状态为从阵列中移除项目的反应

时间:2018-12-14 15:19:20

标签: javascript arrays reactjs

我有一个react组件,该组件在加载时会从api端点获取“问题”列表。然后,将它们显示在表格中。单击某个元素后,它将发送POST请求,告知该服务器问题已解决。一切正常,但是现在,如果POST请求返回200,则需要它从状态(因此从表)中删除该问题。我已经尝试过下面的代码,但是它说无法在this.state.issues行上读取undefined的属性“ state”,表明它不知道“ this”是什么。

class IssueScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  componentDidMount() {
    fetch(`${apiRoot}/${this.props.match.params.id}`, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Token ${this.props.auth.token}`
      }
    })
      .then(response => response.json())
      .then(response =>
        this.setState({
          id: response.id,
          issues: response.issues
        })
      );
  }

  resolveIssue(issueID) {
    fetch(`${apiRoot}resolve_issue/`, {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Token ${this.props.auth.token}`
      },
      body: JSON.stringify({
        id: issueID
      })
    }).then(function(res) {
      if (res.status === 200) {
        for (var i = 0; i < this.state.issues.length - 1; i++) {
          if (this.state.issues[i].id === issueID) {
            this.setState({ issues: this.state.issues.splice(i, 1) });
          }
        }
      } else {
        console.log("Problem");
      }
    });
  }

resolveIssue由以下人员调用: this.resolveIssue(id);在代码中更进一步。

4 个答案:

答案 0 :(得分:0)

首先将函数表达式更改为箭头函数,因此this将指向正确的命名空间。

resolveIssue = (issueID) => {

以及屁股:

.then((res) => {

第二,Array#splice在原位工作,这意味着将直接改变状态。正确绑定resolveIssue函数或将其更改为箭头函数后,您的应用可能会由于mutation state错误而崩溃。我建议您改用spread syntax

类似的东西:

this.setState({ issues: 
    [...this.state.issues.slice(0, i), ...this.state.issues.slice(i + 1)],
});

答案 1 :(得分:0)

您需要为this关键字使用箭头功能,才能在脚本结尾处使用匿名功能。

代码的最后一部分应如下所示。

 resolveIssue = (issueID) => {
    fetch(`${apiRoot}resolve_issue/`, {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Token ${this.props.auth.token}`
      },
      body: JSON.stringify({
        id: issueID
      })
    }).then((res) => {
      if (res.status === 200) {
        for (var i = 0; i < this.state.issues.length - 1; i++) {
          if (this.state.issues[i].id === issueID) {
            this.setState({ issues: this.state.issues.splice(i, 1) });
          }
        }
      } else {
        console.log("Problem");
      }
    });
  }

关于箭头功能:

引用developer.mozilla.org

  

两个因素影响了箭头功能的引入:较短   功能,并且没有此关键字。

它进一步指出箭头功能没有分开

  

直到箭头功能,每个新功能都定义了自己的此值   (根据调用函数的方式,如果是   构造函数,在严格模式函数调用中未定义,基础对象   如果该函数被称为“对象方法”等)。这证明了   面向对象的编程风格不理想。

     

箭头功能不具有此功能;这个的值   使用封闭的词汇上下文,即箭头函数遵循   正常的变量查找规则。所以在寻找这个   在当前范围内不存在,他们最终从其发现   封闭范围。因此,在以下代码中,   传递给setInterval的函数具有与此相同的值   词汇包围函数

function Person(){

      this.age = 0;

      setInterval(() => {
        this.age++; // |this| properly refers to the Person object
      }, 1000);
    }

var p = new Person();

developer.mozilla.org中引号中的内容是我的。 希望有帮助。

答案 2 :(得分:0)

this内使用function() {}时引用的上下文与定义状态的上下文不同。如果要使用箭头功能this将是正确的,因为它会“自动绑定”。

您可以在此处了解更多信息:https://medium.com/komenco/react-autobinding-2261a1092849

如果我可以提出一种更优雅的解决方案,将其从状态中移除(未经测试)。

  if (res.status === 200) {
        this.setState({ issues: this.state.issues.filter(issue => issue.id !== issueID) });
  } else {
    console.log("Problem");
  } 

答案 3 :(得分:0)

亚历克斯。

对于代码的这一部分:

}).then(function(res) {
      if (res.status === 200) {
        for (var i = 0; i < this.state.issues.length - 1; i++) {
          if (this.state.issues[i].id === issueID) {
            this.setState({ issues: this.state.issues.splice(i, 1) });
          }
        }
      } else {
        console.log("Problem");
      }
    });

...看来this未绑定到正确的上下文。将then中包含的函数提取到类方法中可能会有所帮助。然后将this绑定到状态对象下方构造函数内部的新方法。

箭头功能可以在这里工作;但是,我建议您不要使用箭头功能,就像其他人建议的那样,因为每次调用resolveIssue时您实际上都是在重新绑定上下文(这可能导致 最好将这个函数引入一个新方法中,并在构造函数中一次绑定this上下文,以提高性能和可读性(如果适用)。

好运。