我有以下代码。
import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import axios from "axios";
var config = {
headers: {
Accept: "application/json; odata=verbose",
Authorization: "Bearer " + access_token,
},
};
class Searchbar extends React.Component {
async componentWillMount() {
await axios.get(contracts, config).then((res) => {
this.setState({ allContracts: res.data });
});
}
render() {
return (
<div className="searchbar_wrapper">
<Autocomplete
freeSolo
id="contract-search-bar"
disableClearable
options={contracts.map((option) => option.name)}
onChange={(event, value) => {
let selectedContractID =(value)
}}
renderInput={(params) => (
<TextField
{...params}
label="Search"
margin="normal"
variant="outlined"
InputProps={{ ...params.InputProps, type: "search" }}
/>
)}
/>
</div>
);
}
}
export default Searchbar;
我使用组件将加载,因为我想让这个函数在渲染我的组件之前先进行调用... axios调用会得到如下的结果。
results = [
{ name: "aaa" },
{ name: "bb" },
{ name: "cccc" },
];
结果会有超过500个条目...
我的问题是,当组件渲染时,它一直在说。
Cannot read property 'allContracts' of null
原因是axios函数还没有得到结果... ...
请告诉我怎样才能延迟渲染,等待axios先得到结果,然后继续渲染。
这将有助于。不需要 ComponentWillMount. 此外,还需要 错误处理。
state = {
allContracts: null,
error: false
}
componentDidMount(){
axios.get(contracts, config)
.then((res) => {
this.setState({ allContracts: res.data });
})
.catch((err) => this.setState({error: true}))
}
render() {
if(!state.allContracts && !this.state.error){
return null; // add a spinner or something until the posts are loaded
}
if(this.state.error){
return 'Something wrong happened...' // just an example of error
}
return // this will run after the posts are loaded
}
基本上可以保持一个 "加载 "状态,当 loading
是 true
你可以像@pirhan所说的那样,在组件中渲染一个旋转器或其他东西。
你可以像@pirhan提到的那样做。
constructor() {
this.state = {
isLoaded: false
}
}
async componentDidMount() {
const res = await axios.get(contracts, config);
this.setState({ allContracts: res.data, isLoaded: true });
}
render() {
if (!this.state.isLoaded) {
return null /* or a loader/spinner */
}
return "I'm loaded ok."
}
管理一个加载状态以及定义你的状态,就像这样:
import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import axios from "axios";
var config = {
headers: {
Accept: "application/json; odata=verbose",
Authorization: "Bearer " + access_token,
},
};
class Searchbar extends React.Component {
state = { //define state here
allContracts: []
}
async componentDidMount() {
await axios.get(contracts, config).then((res) => {
this.setState({ allContracts: res.data });
});
}
render() {
return (
<div className="searchbar_wrapper">
{ allContracts.length > 0 ? //wait for data - manage loading state
<Autocomplete
freeSolo
id="contract-search-bar"
disableClearable
options={allContracts.map((option) => option.name)}
onChange={(event, value) => {
let selectedContractID =(value)
}}
renderInput={(params) => (
<TextField
{...params}
label="Search"
margin="normal"
variant="outlined"
InputProps={{ ...params.InputProps, type: "search" }}
/>
)}
/>
: <h1>Loading.. </h1>
</div>
);
}
}
export default Searchbar;