首页 > 解决方案 > 为什么在 setState 中获取时会进行两次网络调用?

问题描述

当我在 setState 中使用 fetch 时,该函数发出两个网络请求,但我期望一个请求。

为什么会发生这种情况以及如何预防?

import React from 'react';

class TestFetch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {

    this.setState(() => {

      fetch('http://example.com/', {
        mode: 'no-cors'
      })
        .then(data => {
          console.log(data)
        });
      });
  }

  render() {
    return (
      <button onClick={this.handleClick}> Test </button>
    )
  }
}

export default TestFetch

获取中带有 setState 的另一个版本。现在我有一个网络调用,但单击后我的状态中有两个值:

import React from 'react';

class TestFetch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      'newItems': []
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {

    fetch('http://example.com/', {
      mode: 'no-cors'
    })
      .then(data => {

        this.setState((state) => {
          state.newItems.push("value")
        })

        console.log(this.state)
      });
  }

  render() {
    return (
      <button onClick={this.handleClick}> Test </button>
    )
  }
}

export default TestFetch

好的,基本上它在这个例子中也有这个效果:

import React from 'react';

class TestFetch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      'newItems': []
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => {
      state.newItems.push("value")
    })
    console.log(this.state);
  }

  render() {
    return (
      <button onClick={this.handleClick}> Test </button>
    )
  }
}

export default TestFetch

标签: reactjsfetchsetstate

解决方案


不要在 setState 中进行 api 调用。获取状态变量并将 api 响应数据存储在其中,并在需要时使用状态变量。

 import React from 'react';
    
    class TestFetch extends React.Component {
      constructor(props) {
        super(props);
        this.state = {appData: null};
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
    
     fetch('http://example.com/', {
            mode: 'no-cors'
          })
            .then(data => {
              console.log(data)
     this.setState(() => {appData: data});
            });
       
      }
    
      render() {
        return (
          <button onClick={this.handleClick}> Test </button>
        )
      }
    }
    
    export default TestFetch

推荐阅读