我正在尝试使用axios显示来自API查询的结果。在下拉选择表单中选择一个值后,查询将更改。我遇到的问题是似乎“ current_newspaper”值没有及时更新,因此发生的情况是页面在第二次单击后刷新,而不仅仅是在我选择了正确的选项后刷新。
例如,我单击选项“ newstest2”,然后查询“ getNews”进行查询并刷新具有PREVIOUS值的信息(“ newstest”)。但是,从这种情况下,当我单击选项“ newstest3”时,将使用“ newstest2”中的值进行查询。因此,似乎有些延迟。我认为问题与状态有关,可能是因为this.state没有及时更新,或者因为我正在刷新数据之前进行查询。
您知道可能是什么问题吗?我很困在这里。
谢谢!
class App extends Component {
constructor(props) {
super(props);
this.state = {
news: [],
isLoading: true,
errors: null,
current_newspaper: "newstest"
};
this.handleChange = this.handleChange.bind(this);
}
getNews() {
// We're using axios instead of Fetch
axios
// The API we're requesting data from
.post("http://127.0.0.1:5000/api/v1/"+this.state.current_newspaper)
// Once we get a response, we'll map the API endpoints to our props
.then(response =>
response.data.map(newses => ({
title: `${newses.title}`,
description: `${newses.description}`,
url: `${newses.url}`,
lastdate: `${newses.scrape_lastdate}`
}))
)
// Let's make sure to change the loading state to display the data
.then(news => {
this.setState({
news,
isLoading: false
});
})
// We can still use the `.catch()` method since axios is promise-based
.catch(error => this.setState({ error, isLoading: false }));
}
componentDidMount() {
this.getNews();
}
handleChange(event) {
this.setState({current_newspaper: event.target.value})
this.getNews();
}
handleSubmit(event){
event.preventDefault();
}
render(){
const { isLoading, news } = this.state;
return (
<div className="App">
<Navbar bg="dark" variant="dark">
<Navbar.Brand href="#home">
<img
alt=""
src="/logo.svg"
width="30"
height="30"
className="d-inline-block align-top"
/>
{' '}
testpage
</Navbar.Brand>
</Navbar>
<Container>
<Row>
<Col>
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="exampleForm.SelectCustom" >
<Form.Control as="select" onChange={this.handleChange} value={this.state.current_newspaper} custom>
<option value="newstest">newstest</option>
<option value="newstest2">newstest2</option>
<option value="newstest3">newstest3</option>
</Form.Control>
</Form.Group>
</Form>
</Col>
</Row>
</Container>
<Container>
<Row>
{!isLoading ? (
news.map(newses => {
const { title, description, url, lastdate } = newses;
return (
<Card key = {title} style={{ width: '18rem' }}>
<Card.Body>
<Card.Link href={url}>
{title}
</Card.Link>
<Card.Text>
{description}
</Card.Text>
<Card.Text>
{lastdate}
</Card.Text>
</Card.Body>
</Card>
);
})
) : (
<p>Loading...</p>
)}
</Row>
</Container>
setState
不会立即更新状态-而是it's a request for a change of state。这意味着在handleChange
中,当getNews
之后立即调用setState
时,该状态仍然是旧状态。
将
setState()
视为请求,而不是立即命令来更新组件。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React不保证状态更改会立即应用。
setState()
并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用this.state
之后立即读取setState()
是潜在的陷阱。而是使用componentDidUpdate
或setState
回调(setState(updater, callback)
),可以保证在应用更新后都会触发这两种方法。如果需要基于先前的状态来设置状态,请阅读下面的updater参数。
您需要在this.getNews()
或回调中执行componentDidUpdate
:
handleChange(event) {
this.setState({ current_newspaper: event.target.value }, () => {
this.getNews();
})
}
或
componentDidUpdate(prevProps) {
if (this.props.current_newspaper !== prevProps.current_newspaper) {
this.getNews();
}
}