我有一个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);
在代码中更进一步。
答案 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");
}
});
}
关于箭头功能:
两个因素影响了箭头功能的引入:较短 功能,并且没有此关键字。
它进一步指出箭头功能没有分开:
直到箭头功能,每个新功能都定义了自己的此值 (根据调用函数的方式,如果是 构造函数,在严格模式函数调用中未定义,基础对象 如果该函数被称为“对象方法”等)。这证明了 面向对象的编程风格不理想。
箭头功能不具有此功能;这个的值 使用封闭的词汇上下文,即箭头函数遵循 正常的变量查找规则。所以在寻找这个 在当前范围内不存在,他们最终从其发现 封闭范围。因此,在以下代码中, 传递给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
上下文,以提高性能和可读性(如果适用)。
好运。