为什么在setState之前调用了setState中没有参数的函数调用?

时间:2019-07-09 15:55:58

标签: javascript reactjs

正如another question中向我指出的,如果我在setStaterandomQuoteIndex()中有一个不带参数的函数调用,并且该函数使用的状态是在{{1 }},它在setState之前被调用。

setState

这会导致错误,因为在 componentDidMount() { fetch('https://gist.githubusercontent.com/nataliecardot/0ca0878d2f0c4210e2ed87a5f6947ec7/raw/1802a693d02ea086817e46a42413c0df4c077e3b/quotes.json') .then(response => response.json()) .then(quotes => this.setState({ quotes, randomQuoteIndex: this.randomQuoteIndex(), isDoneFetching: true })); } randomQuoteIndex() { return random(0, this.state.quotes.length - 1); } 调用时quotes的状态不可用。

但是,如果我将randomQuoteIndex()更改为改为使用传递的randomQuoteIndex()参数,则如下所示。

quotes

这不是我期望的;我假设componentDidMount() { fetch('https://gist.githubusercontent.com/nataliecardot/0ca0878d2f0c4210e2ed87a5f6947ec7/raw/1802a693d02ea086817e46a42413c0df4c077e3b/quotes.json') .then(response => response.json()) .then(quotes => this.setState({ quotes, randomQuoteIndex: this.randomQuoteIndex(quotes), isDoneFetching: true })); } randomQuoteIndex(quotes) { return random(0, quotes.length - 1); } 的状态在调用quotes时可用,因为它是在randomQuoteIndex()中调用的。为什么setStaterandomQuoteIndex()之前被调用?

2 个答案:

答案 0 :(得分:2)

这是因为 {% extends "blog/base.html" %} {% block title %}{{ post.title }}{% endblock %} {% block content %} <h1>{{ post.title }}</h1> <p class="date"> Published {{ post.publish }} by {{ post.author }} </p> {{ post.body|linebreaks }} <p> <a href="{% url 'blog:post_share' post.id %}"> Share this post </a> </p> <h2>Similar posts</h2> {% for post in similar_posts %} <p> <a href="{{ post.get_absolute_url }}">{{ post.title }}</a> </p> {% empty %} There are no similar posts yet. {% endfor %} {% with comments.count as total_comments %} <h2> {{ total_comments }} comment{{ total_comments|pluralize }} </h2> {% endwith %} {% for comment in comments %} <div class="comment"> <p class="info"> Comment {{ forloop.counter }} by {{ comment.name }} {{ comment.created }} </p> {{ comment.body|linebreaks }} </div> {% empty %} <p>There are no comments yet.</p> {% endfor %} {% if new_comment %} <h2>Your comment has been added.</h2> {% else %} <h2>Add a new comment</h2> <form action="." method="post"> {{ comment_form.as_p }} {% csrf_token %} <p><input type="submit" value="Add comment"></p> </form> {% endif %} {% endblock %} 是异步操作。您仍然可以使用setState作为回调函数来使用原始功能

setState

因此,实质上,一旦执行componentDidMount() { fetch('https://gist.githubusercontent.com/nataliecardot/0ca0878d2f0c4210e2ed87a5f6947ec7/raw/1802a693d02ea086817e46a42413c0df4c077e3b/quotes.json') .then(response => response.json()) .then(quotes => this.setState({ quotes, isDoneFetching: true }, () => { this.setState({ randomQuoteIndex: this.randomQuoteIndex(), }); //this callback will be executed after your state is updated. })); } randomQuoteIndex() { return random(0, this.state.quotes.length - 1); } 函数,更新的值将仅在更新生命周期结束后反映出来,这意味着您可以通过setState方法或通过使用{ {1}}用作回调。

我不推荐这种解决方案,但是在这种情况下,函数componentDidUpdate将获得更新的状态值而无需传递任何参数。

答案 1 :(得分:1)

那是因为在将对象传递给setState时,您正在执行对this.randomQuoteIndex的内联调用。

状态。该州尚不存在报价。

constructor() {
    this.state = { quotes: [] };

}

componentDidMount() {
    fetch('https://gist.githubusercontent.com/nataliecardot/0ca0878d2f0c4210e2ed87a5f6947ec7/raw/1802a693d02ea086817e46a42413c0df4c077e3b/quotes.json')
      .then(response => response.json())
      .then(quotes => {

          this.setState({
            quotes,
            randomQuoteIndex: this.randomQuoteIndex(),
            isDoneFetching: true
        })
      });

  }

  randomQuoteIndex() {
    return random(0, this.state.quotes.length - 1);
  }