正如another question中向我指出的,如果我在setState
,randomQuoteIndex()
中有一个不带参数的函数调用,并且该函数使用的状态是在{{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()
中调用的。为什么setState
在randomQuoteIndex()
之前被调用?
答案 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);
}