Reactjs Select表单具有一键式延迟更新

问题描述 投票:0回答:1

我正在尝试使用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>
reactjs react-bootstrap
1个回答
1
投票

setState不会立即更新状态-而是it's a request for a change of state。这意味着在handleChange中,当getNews之后立即调用setState时,该状态仍然是旧状态。

setState()视为请求,而不是立即命令来更新组件。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React不保证状态更改会立即应用。

setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用this.state之后立即读取setState()是潜在的陷阱。而是使用componentDidUpdatesetState回调(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();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.