Javascript React JS-can';t对尚未安装的组件调用setState
我在React JS中有我的应用程序。我正在从一个API获取数据http://localhost:8080/api/suppliers/supplier/list: 以下是我从Google Chrome控制台中的REST API获得的数据:Javascript React JS-can';t对尚未安装的组件调用setState,javascript,reactjs,rxjs,axios,Javascript,Reactjs,Rxjs,Axios,我在React JS中有我的应用程序。我正在从一个API获取数据http://localhost:8080/api/suppliers/supplier/list: 以下是我从Google Chrome控制台中的REST API获得的数据: 0:{ id: 4 supplierFirstname: "Tom" supplierLastName: "ABC" supplierTitle: "TomTheSupplie
0:{
id: 4
supplierFirstname: "Tom"
supplierLastName: "ABC"
supplierTitle: "TomTheSupplier"
accountNumber: 1122234444
address: "111 ADrive, 1234 ST."
companyName: "TheTom Company & Associates"
email: "tomtomjayjay@email.com"
hourlyRate: 29
phoneNumber: 123456789
otherPhoneNumber: 1023456789
paymentTerms: "Credit"
notes: "Some Supplier"
createdAt: null
typeOfGoods: "Supplies"
website: "www.abc_123.com"
products: [{…}]
components:
[
0: {id: 5, name: "AComponent", unit: null, quantity: 0, componentCost: 0, …}
]
}
这是我的代码:
class SupplierData extends React.Component {
constructor(props) {
super(props);
this.state = {
supplier: [
{
id: 0,
supplierTitle: "Supplier Title",
supplierFirstName: "First Name",
supplierLastName: "Last Name",
companyName: "Company Name",
phoneNumber: "Phone Number",
otherPhoneNumber: "Phone Number (Other)",
accountNumber: "Account Number",
email: "Email",
address: "Address",
website: "Website",
hourlyRate: "Hourly Rate",
typeOfGoods: "Type Of Goods",
paymentTerms: "Payment Terms",
createdAt: "Created At",
notes: "Notes",
products: "Products",
components: "Components",
},
],
errorMessage: [],
};
this.ListAllSuppliers = this.ListAllSuppliers.bind(this);
}
ListAllSuppliers = async () => {
return await axios
.get(`http://localhost:8080/api/suppliers/supplier/list`)
.then((response) => {
let apiResults = response.data;
console.log(apiResults);
this.setState({ supplier: apiResults }); <--- The error happens here.
})
.catch((error) => {
this.setState({ errorMessage: this.state.errorMessage.push(error) });
});
};
componentDidMount() {
this.ListAllSuppliers();
}
}
export default SupplierData;
问题:
我想设定状态
有什么方法可以修复上述错误?代码本身基本上没有问题,尽管您混合了对
.then
和的调用。catch
和异步/wait
,这不是最佳做法,并且您对arrow函数不必要地使用了绑定
听起来您的组件在启动axios
调用之后和返回之前正在卸载,这导致您在未装载的组件上调用setState
。(尽管错误的措辞与我看到的略有不同。)
为了避免这种情况,您可以通过在选项中传递cancelToken
并在componentWillUnmount
的source
上使用cancel
方法,从componentWillUnmount
调用axios。(内置提供了相同的功能,通过。)(如果您正在执行不支持取消的操作,作为回退,您可以设置此项。在组件中卸载的将卸载
,然后检查此项,如果您看到此项为真,则不调用设置状态
)
代码还有一些其他问题;这是一个更新的版本,上面提到了cancel令牌以及其他内联解决的问题(请参阅注释):
乍一看很好…从构造函数中删除这一行this.listallproviders=this.listallproviders.bind(this)代码>。您不需要此功能,因为listalsuppliers
是一个箭头函数HI,欢迎使用SO!碰巧您在这个问题中添加了不相关的标记。标签node.js
和rxjs
与问题主题无关。请考虑一个标签可能与你的特定问题无关,即使它与你的项目相关。@托马斯-谢谢!我搜索“信号”是因为。(我还搜索了“abort”,并认为我搜索了[我喜欢的词]“cancel”,但显然不是!)@abc_123-上面的调用非常简单。如果您没有在后端看到它,那么这是一个与此问题无关的后端问题。我希望你能弄明白!
Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might
indicate a bug in your application. Instead, assign to `this.state` directly or define a `state =
{};` class property with the desired state in the SupplierData component.
class SupplierData extends React.Component{
constructor(props){
super(props);
this.state = {
supplier: [
{
id: 0,
supplierTitle: "Supplier Title",
supplierFirstName: "First Name",
supplierLastName: "Last Name",
companyName: "Company Name",
phoneNumber: "Phone Number",
otherPhoneNumber: "Phone Number (Other)",
accountNumber: "Account Number",
email: "Email",
address: "Address",
website: "Website",
hourlyRate: "Hourly Rate",
typeOfGoods: "Type Of Goods",
paymentTerms: "Payment Terms",
createdAt: "Created At",
notes: "Notes",
products: "Products",
components: "Components"
},
],
errorMessage: [],
};
// No need to bind `listAllSuppliers`, you don't use it as a callback
// A single cancel source that can cancel multiple operations
this.cancelSource = axios.CancelToken.source();
}
// Use an async method
// Note the initial lower case `l` (not `L`), which is standard in JavaScript
async listAllSuppliers() {
// In an `async` function, you use `try`/`catch` and `await`, not
// `.then` / `.catch` methods
try {
const response = await axios.get(
`http://localhost:8080/api/suppliers/supplier/list`,
{cancelToken: this.cancelSource.token}
);
const supplier = response.data;
console.log(supplier)
this.setState({supplier});
} catch (error) {
// Updating state based on existing state requires the callback form
// of `setState` , and you must never directly modify state objects
this.setState(({errorMessage}) => ({
errorMessage: [...errorMessage, error]
}));
}
}
componentDidMount() {
this.listAllSuppliers();
}
componentWillUnmount() {
// Cancel any outstanding axios calls
this.cancelSource.cancel("Component unmounted");
}
// Presumably you do have a `render` method, you'd get a different React error if you didn't
render() {
// ...
}
}
export default SupplierData;