Javascript 在POST请求后以状态从数组中移除项

Javascript 在POST请求后以状态从数组中移除项,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,我有一个react组件,它在加载时从api端点获取“问题”列表。然后将它们显示在表中。单击某个元素时,它会发送一个POST请求,告知服务器问题已经解决。这一切都很好,但是现在,如果POST请求返回200,我需要它将该问题从状态中删除(因此从表中删除)。我尝试了下面的代码,但它说它无法读取行this.state.issues上未定义的属性“state”,这表明它不知道什么是“this” class IssueScreen extends Component { constructor(prop

我有一个react组件,它在加载时从api端点获取“问题”列表。然后将它们显示在表中。单击某个元素时,它会发送一个POST请求,告知服务器问题已经解决。这一切都很好,但是现在,如果POST请求返回200,我需要它将该问题从状态中删除(因此从表中删除)。我尝试了下面的代码,但它说它无法读取行
this.state.issues
上未定义的属性“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");
      }
    });
  }
class IssueScreen扩展组件{
建造师(道具){
超级(道具);
this.state={};
}
componentDidMount(){
fetch(`${apiRoot}/${this.props.match.params.id},`{
方法:“获取”,
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
授权:`Token${this.props.auth.Token}`
}
})
.then(response=>response.json())
。然后(响应=>
这是我的国家({
id:response.id,
问题:答复.问题
})
);
}
解决问题(issueID){
获取(`${apiRoot}解决\u问题/`{
方法:“张贴”,
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
授权:`Token${this.props.auth.Token}`
},
正文:JSON.stringify({
id:issueID
})
}).然后(功能(res){
如果(资源状态===200){
for(var i=0;i
resolveIssue
由以下人员调用:
this.resolveIssue(id);
在代码中进一步说明。

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

resolveIssue = (issueID) => {
以及:

.then((res) => {
其次,
Array#splice
在原位工作,这意味着将直接改变状态。正确绑定
resolveIssue
函数或将其更改为箭头函数后,您的应用程序可能会因
突变状态
错误而崩溃。我建议您改用
扩展语法

比如:

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

您需要为
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引用的文本中的重点是我的。
希望对您有所帮助。

当您使用
时,在
函数({}
中引用的上下文与定义状态的上下文不同。如果您使用箭头函数
,这将是正确的,因为它是“自动绑定的”

您可以在此处阅读更多内容:

如果我能建议一个更优雅的解决方案,从状态中删除此项(未测试)

亚历克斯

对于代码的这一部分:

}).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");
      }
    });
然后(函数(res){ 如果(资源状态===200){ for(var i=0;i
。。。似乎
未绑定到正确的上下文。将
中包含的函数拉出到类方法中可能会有所帮助。然后将此
绑定到state对象下面的构造函数中的新方法

这里可以使用箭头函数;但是,我建议您不要像其他人建议的那样使用箭头函数,因为每次调用
resolveIssue
(这可能会影响性能)时,您实际上都在重新绑定上下文最好将这个函数拉到一个新方法中,并在构造函数中绑定一次
这个
上下文,以提高性能和可读性,如果这样做对您有效的话


祝您好运。

您是否将
解决问题
绑定到组件中的任何类?没有。。。我是新来的。我想这是有道理的。你必须绑定它,这样它才能访问类状态。请看这里:这是有道理的,谢谢,但即使使用箭头功能,我也会遇到同样的问题。当我将函数(res)设置为箭头函数时,它开始工作too@Alex试着一般使用箭头函数。这有助于避免很多问题。我开始有这种印象;)我的印象是它只是一种简写,我没有意识到它改变了名称空间。吸取教训!肯定更优雅,但它似乎删除了除我单击的问题之外的所有问题,所以我认为它需要反转。很容易修复,即使是我。谢谢:)对不起!是的,确实如此,写得很快,没有验证,但很高兴它确实验证了;更重要的是,教了我一些关于编写惯用JavaScript的知识!
  if (res.status === 200) {
        this.setState({ issues: this.state.issues.filter(issue => issue.id !== issueID) });
  } else {
    console.log("Problem");
  } 
}).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");
      }
    });