{"componentChunkName":"component---src-templates-docs-js","path":"/docs/faq-state.html","result":{"data":{"markdownRemark":{"html":"<h3 id=\"what-does-setstate-do\"><a href=\"#what-does-setstate-do\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Что делает <code class=\"gatsby-code-text\">setState</code>? </h3>\n<p>Метод <code class=\"gatsby-code-text\">setState()</code> планирует изменение объекта состояния (<code class=\"gatsby-code-text\">state</code>) компонента. Когда состояние меняется, компонент рендерится повторно.</p>\n<h3 id=\"what-is-the-difference-between-state-and-props\"><a href=\"#what-is-the-difference-between-state-and-props\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Какая разница между <code class=\"gatsby-code-text\">state</code> и <code class=\"gatsby-code-text\">props</code>? </h3>\n<p><a href=\"/docs/components-and-props.html\"><code class=\"gatsby-code-text\">props</code></a> (намеренно сокращённо от англ. «properties» — свойства) и <a href=\"/docs/state-and-lifecycle.html\"><code class=\"gatsby-code-text\">state</code></a> — это обычные JavaScript-объекты. Несмотря на то, что оба содержат информацию, которая влияет на то, что увидим после рендера, есть существенное различие: <code class=\"gatsby-code-text\">props</code> передаётся <em>в</em> компонент (служат как параметры функции), в то время как <code class=\"gatsby-code-text\">state</code> находится <em>внутри</em> компонента (по аналогии с переменными, которые объявлены внутри функции).</p>\n<p>Несколько полезных ресурсов для дальнейшего изучения, в каких случаях использовать <code class=\"gatsby-code-text\">props</code>, а в каких — <code class=\"gatsby-code-text\">state</code>:</p>\n<ul>\n<li><a href=\"https://github.com/uberVU/react-guide/blob/master/props-vs-state.md\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Props vs. State</a></li>\n<li><a href=\"https://lucybain.com/blog/2016/react-state-vs-pros/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ReactJS: Props vs State</a></li>\n</ul>\n<h3 id=\"why-is-setstate-giving-me-the-wrong-value\"><a href=\"#why-is-setstate-giving-me-the-wrong-value\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Почему <code class=\"gatsby-code-text\">setState</code> даёт неверное значение? </h3>\n<p>В React как <code class=\"gatsby-code-text\">this.props</code>, так и <code class=\"gatsby-code-text\">this.state</code> представляют значения, которые <em>уже были отрендерены</em>, например, то, что видите на экране.</p>\n<p>Вызовы <code class=\"gatsby-code-text\">setState</code> являются асинхронными, поэтому не стоит рассчитывать, что <code class=\"gatsby-code-text\">this.state</code> отобразит новое значение мгновенно после вызова <code class=\"gatsby-code-text\">setState</code>. Необходимо добавить функцию, которая сработает только после обновления состояния, если нужно получить новое значение, основанное на текущем состоянии (ниже подробный пример).</p>\n<p>Пример кода, который <em>не</em> будет работать так, как ожидаем:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Примечание: это *не* сработает, как ожидалось.</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token literal-property property\">count</span><span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">handleSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Допустим, что `this.state.count` начинается с 0.</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// Когда React делает последующий рендер компонента, `this.state.count` будет 1, хотя мы ожидаем 3.</span>\n\n  <span class=\"token comment\">// Так происходит, потому что функция `incrementCount()` берёт своё значение из `this.state.count`,</span>\n  <span class=\"token comment\">// но React не обновляет `this.state.count`, пока компонент не отрендерится снова.</span>\n  <span class=\"token comment\">// Получается, что `incrementCount()` обращается к текущему значению `this.state.count`, а это 0 каждый раз, и добавляет 1.</span>\n\n  <span class=\"token comment\">// Как исправить это — разберём ниже!</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Далее перейдём к исправлению указанной проблемы.</p>\n<h3 id=\"how-do-i-update-state-with-values-that-depend-on-the-current-state\"><a href=\"#how-do-i-update-state-with-values-that-depend-on-the-current-state\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Как обновить состояние значениями, которые зависят от текущего состояния? </h3>\n<p>Нужно добавить функцию вместо объекта к <code class=\"gatsby-code-text\">setState</code>, которая будет срабатывать только на самой последней версии состояния (пример ниже).</p>\n<h3 id=\"what-is-the-difference-between-passing-an-object-or-a-function-in-setstate\"><a href=\"#what-is-the-difference-between-passing-an-object-or-a-function-in-setstate\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>В чём разница между добавлением объекта или функции к <code class=\"gatsby-code-text\">setState</code>? </h3>\n<p>Добавление функции даёт вам доступ к текущему состоянию внутри самой функции. Так как <code class=\"gatsby-code-text\">setState</code> вызовы «сгруппированы», это помогает связать изменения и гарантирует, что они будут выполняться друг за другом, а не конфликтовать.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Важно: используем `state` вместо `this.state` при обновлении.</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span><span class=\"token literal-property property\">count</span><span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">handleSomething</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Возьмём снова для примера, что `this.state.count` начинается с 0.</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Если посмотреть на значение `this.state.count` сейчас, это будет по-прежнему 0.</span>\n  <span class=\"token comment\">// Но когда React отрендерит компонент снова, будет уже 3.</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><a href=\"/docs/react-component.html#setstate\">Прочитать больше про setState</a></p>\n<h3 id=\"when-is-setstate-asynchronous\"><a href=\"#when-is-setstate-asynchronous\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Когда <code class=\"gatsby-code-text\">setState</code> работает асинхронно? </h3>\n<p>В настоящее время <code class=\"gatsby-code-text\">setState</code> работает асинхронно внутри обработчиков событий.</p>\n<p>Это даёт гарантию, например, когда <code class=\"gatsby-code-text\">Родитель</code> и <code class=\"gatsby-code-text\">Ребёнок</code> вызывают <code class=\"gatsby-code-text\">setState</code> во время клика, <code class=\"gatsby-code-text\">Ребёнок</code> не будет рендериться дважды. Вместо этого React «откладывает» обновление состояния в самый конец событий в браузере. Это помогает сильно повысить производительность больших приложений.</p>\n<p>Но не стоит полностью полагаться на такое поведение. В будущих версиях React будет использовать отложенные обновления состояния по умолчанию не только в обработчиках событий.</p>\n<h3 id=\"why-doesnt-react-update-thisstate-synchronously\"><a href=\"#why-doesnt-react-update-thisstate-synchronously\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Почему React не обновляет <code class=\"gatsby-code-text\">this.state</code> синхронно? </h3>\n<p>Как говорилось ранее, React намеренно «ждёт» пока все компоненты вызовут <code class=\"gatsby-code-text\">setState()</code> в своих обработчиках событий прежде чем начать повторный рендер. Это избавляет от ненужных повторных рендеров.</p>\n<p>Вы можете задаваться вопросом: почему React не может просто сразу обновить <code class=\"gatsby-code-text\">this.state</code> без повторного рендеринга?</p>\n<p>На это есть две причины:</p>\n<ul>\n<li>Это нарушит логику работы <code class=\"gatsby-code-text\">props</code> и <code class=\"gatsby-code-text\">state</code>, а значит станет причиной многих багов, которые будет сложно исправить.</li>\n<li>Это сделало бы невозможным реализацию некоторых возможностей, над которыми мы сейчас работаем.</li>\n</ul>\n<p>Этот <a href=\"https://github.com/facebook/react/issues/11527#issuecomment-360199710\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub-комментарий</a> рассматривает конкретные примеры, которые помогут глубже изучить этот вопрос.</p>\n<h3 id=\"should-i-use-a-state-management-library-like-redux-or-mobx\"><a href=\"#should-i-use-a-state-management-library-like-redux-or-mobx\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Стоит ли использовать такие библиотеки, как Redux или MobX? </h3>\n<p><a href=\"https://redux.js.org/faq/general#when-should-i-use-redux\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Возможно.</a></p>\n<p>Но вообще будет здорово сначала изучить React, прежде чем переходить к библиотекам. Можно создать готовое рабочее приложение, используя только React.</p>","frontmatter":{"title":"Состояние компонента","next":null,"prev":null},"fields":{"path":"content/docs/faq-state.md","slug":"docs/faq-state.html"}}},"pageContext":{"slug":"docs/faq-state.html"}},"staticQueryHashes":[]}