ReactJs - 无法在 axios 调用中访问 setState

ReactJs - can't access setState inside axios call

我在 axios 调用中将状态设置为变量 isCorrectAnswer 时遇到问题。我在控制台日志中收到错误 Cannot read properties of undefined (reading 'setState')。我究竟做错了什么? isCorrectAnswer 变量的初始状态是 constructor(props) {super(props)this.state = { isCorrectAnswer: false }}
axios 调用是

axios.post(
      "API/path/to/ressource",
      postData,
      {
        headers: {
          "X-Access-Token":
            "token",
        },
      }
    )
      .then(function (res) {
        this.setState({
          isCorrectAnswer: res.data.correct //Here im trying to change the state
        }, () => console.log(this.state.isCorrectAnswer)) //and logging into console
      })
      .catch(function (error) {
        console.log(error);
      });

当你调用一个函数(非箭头函数)时,this总是一个隐式参数。

正常功能

我所说的普通函数是指不是方法的函数。

严格模式下 this 的值总是undefined

并且在非严格模式下 this 的值始终是全局对象(window 在浏览器中)

function foo() {
  "use strict";
  return this;
}

function bar() {
  return this;
}

console.log(foo() === undefined); // true
console.log(bar() === window); // true

方法

this指的是调用该方法的对象。

function foo() {
  "use strict";
  return this;
}

const obj = { foo };

console.log(obj.foo() === obj); // true

在你的例子中,传递给 then 的回调是一个普通函数(不是方法),所以它的 this 被设置为 undefined,因此你得到了一个错误。

更新箭头函数,它会解决问题,因为箭头函数没有自己的 this,在箭头函数中 this 是根据词法范围决定的。查看下面的示例:

const getRandomNums = (delay) =>
  new Promise((res) => setTimeout(() => res([5, 2, 3]), delay));

class App extends React.Component {
  constructor() {
    super();
    this.state = { nums: [] };
  }

  componentDidMount() {
    getRandomNums(1500).then((nums) => {
      this.setState({ nums });
    });
  }

  render() {
    return <div>{JSON.stringify(this.state.nums, null, 2)}</div>;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>

你也可以 使用箭头函数代替 function

axios.post(
  "API/path/to/ressource",
  postData,
  {
    headers: {
      "X-Access-Token":
        "token",
    },
  }
)
  .then((res) => {
    this.setState({
      isCorrectAnswer: res.data.correct //Here im trying to change the state
    }, () => console.log(this.state.isCorrectAnswer)) //and logging into console
  })
  .catch((error) => {
    console.log(error);
  });