{"componentChunkName":"component---src-templates-docs-js","path":"/docs/hooks-rules.html","result":{"data":{"markdownRemark":{"html":"<p><em>Hookها</em> ضمیمه جدید ری‌اکت ۱۶.۸ هستند. آن‌ها به شما اجازه می‌دهند تا از state و سایر ویژگی‌های ری‌اکت بدون نوشتن کلاس استفاده کنید.</p>\n<p>Hookها توابع جاوااسکریپت هستند، ولی هنگامی که از آنها استفاده می‌کنید باید از دو قانون تبعیت کنید. ما یک <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">پلاگین آستر</a> برای اجرای خودکار این قوانین برای شما فراهم کردیم.</p>\n<h3 id=\"only-call-hooks-at-the-top-level\"><a href=\"#only-call-hooks-at-the-top-level\" 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>Hookها را فقط در بالاترین سطح فراخوانی کنید</h3>\n<p><strong>Hookها را درون لوپ، شرط، یا توابع در هم تنیده فراخوانی نکنید</strong> به جای آن، همیشه آنها را در بالاترین سطح توابع ری‌اکت فراخوانی کنید. با پیروی از این قوانین، مطمین می‌شوید که Hookها هنگامی که در یک کامپوننت رندر می‌شوند به یک ترتیب فراخوانی می‌شوند. این چیزیست که به ری‌اکت اجازه می‌دهد state hookها را بین چندین فراخوانی از <code class=\"gatsby-code-text\">useState</code> و <code class=\"gatsby-code-text\">useEffect</code> حفظ کند.</p>\n<h3 id=\"only-call-hooks-from-react-functions\"><a href=\"#only-call-hooks-from-react-functions\" 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>Hookها را فقط در توابع ری‌اکتی فراخوانی کنید </h3>\n<p><strong>Hookها را در توابع عادی جاوااسکریپت فراخوانی نکنید.</strong> به جای آن، می‌توانید:</p>\n<ul>\n<li>✅ Hookها را در توابع ری‌اکت فراخوانی کنید.</li>\n<li>✅ Hookها را از Hookها فراخوانی کنید (در صفحه بعدی در موردشان خواهیم <a href=\"/docs/hooks-custom.html\">آموخت</a>).</li>\n</ul>\n<p>با پیروی از این قوانین، متوجه می‌شوید که تمام منطق stateful به وضوح در منبع کد یک کامپوننت قابل مشاهده است.</p>\n<h2 id=\"eslint-plugin\"><a href=\"#eslint-plugin\" 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>پلاگین ESLint </h2>\n<p>ما پلاگینی منتشر کردیم که به آن<a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">eslint-plugin-react-hooks</code></a> گفته می‌شود و این دو قانون را اجباری می‌کند. اگر دوست داشتید می‌توانید این پلاگین را به پروژه خود اضافه کنید.</p>\n<p>این پلاگین به صورت پیش‌فرض در <a href=\"/docs/create-a-new-react-app.html#create-react-app\">Create React App</a> وجود دارد.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"gatsby-code-bash\"><code class=\"gatsby-code-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> eslint-plugin-react-hooks --save-dev</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// Your ESLint configuration</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token string\">\"plugins\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token comment\">// ...</span>\n    <span class=\"token string\">\"react-hooks\"</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token string\">\"rules\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n    <span class=\"token string\">\"react-hooks/rules-of-hooks\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"error\"</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// Checks rules of Hooks</span>\n    <span class=\"token string\">\"react-hooks/exhaustive-deps\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"warn\"</span> <span class=\"token comment\">// Checks effect dependencies</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>اکنون شما میتوانید به پیج صفحه بعد که آموزش <a href=\"/docs/hooks-custom.html\">نوشتن Hook شخصی</a> را می‌دهد جهش داشته باشید.</strong> در ادامه در این پیج می‌خواهیم توضیح دهیم که علت این قوانین چیست.</p>\n<h2 id=\"explanation\"><a href=\"#explanation\" 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>توضیح </h2>\n<p>همانطور که در قبل <a href=\"/docs/hooks-state.html#tip-using-multiple-state-variables\">آموختیم</a>، می توانیم از چندین هوک State و Effect در یک کامپوننت استفاده کنیم.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Form</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// 1. Use the name state variable</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>name<span class=\"token punctuation\">,</span> setName<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 2. Use an effect for persisting the form</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">persistForm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'formData'</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 3. Use the surname state variable</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>surname<span class=\"token punctuation\">,</span> setSurname<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 4. Use an effect for updating the title</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">updateTitle</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    document<span class=\"token punctuation\">.</span>title <span class=\"token operator\">=</span> name <span class=\"token operator\">+</span> <span class=\"token string\">' '</span> <span class=\"token operator\">+</span> surname<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>پس ری‌اکت چگونه می‌فهمد که چه stateای به چه فراخوانی از <code class=\"gatsby-code-text\">useState</code> مرتبط است؟ جواب این‌است که <strong>ری‌اکت به ترتیبی که Hookها فراخوانی می‌شود تکیه می‌کند</strong>. مثال ما کار می‌کند زیرا ترتیب فراخوانی Hookها در هر رندر یکسان است:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// ------------</span>\n<span class=\"token comment\">// First render</span>\n<span class=\"token comment\">// ------------</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span>           <span class=\"token comment\">// 1. Initialize the name state variable with 'Mary'</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>persistForm<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 2. Add an effect for persisting the form</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span>        <span class=\"token comment\">// 3. Initialize the surname state variable with 'Poppins'</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>updateTitle<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 4. Add an effect for updating the title</span>\n\n<span class=\"token comment\">// -------------</span>\n<span class=\"token comment\">// Second render</span>\n<span class=\"token comment\">// -------------</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span>           <span class=\"token comment\">// 1. Read the name state variable (argument is ignored)</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>persistForm<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 2. Replace the effect for persisting the form</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span>        <span class=\"token comment\">// 3. Read the surname state variable (argument is ignored)</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>updateTitle<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 4. Replace the effect for updating the title</span>\n\n<span class=\"token comment\">// ...</span></code></pre></div>\n<p>تا زمانی که ترتیب فراخوانی Hookها بین رندرها یکسان است، ری‌اکت می‌تواند برخی از state های محلی را با هر یک از آنها مرتبط کند. ولی چه می‌شود وقتی که ما Hookای را درون شرطی فراخوانی می‌کنیم (برای مثال، تاثیر <code class=\"gatsby-code-text\">persistForm</code>).</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token comment\">// 🔴 We're breaking the first rule by using a Hook in a condition</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>name <span class=\"token operator\">!==</span> <span class=\"token string\">''</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">persistForm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'formData'</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</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></code></pre></div>\n<p>شرط <code class=\"gatsby-code-text\">name !== &#39;&#39;</code> در اولین رندر صحیح است، پس این Hook را اجرا می‌کنیم. گرچه، در رندر بعدی کاربر ممکن است فرم را خالی کرده باشد و شرط را ناصحیح قرار دهد. و حالا در طول رندر این Hook از رویش میپریم، فراخوانی‌های Hook متفاوت می‌شود:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Mary'</span><span class=\"token punctuation\">)</span>           <span class=\"token comment\">// 1. Read the name state variable (argument is ignored)</span>\n<span class=\"token comment\">// useEffect(persistForm)  // 🔴 This Hook was skipped!</span>\n<span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Poppins'</span><span class=\"token punctuation\">)</span>        <span class=\"token comment\">// 🔴 2 (but was 3). Fail to read the surname state variable</span>\n<span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span>updateTitle<span class=\"token punctuation\">)</span>     <span class=\"token comment\">// 🔴 3 (but was 4). Fail to replace the effect</span></code></pre></div>\n<p>ری‌اکت نمی‌داند که چه چیزی را برای دومین Hook <code class=\"gatsby-code-text\">useState</code> برگرداند. ری‌اکت توقع دارد که دومین فراخوانی درست مثل رندر قبلی Hook در این کامپوننت به افکت <code class=\"gatsby-code-text\">persistForm</code> مرتبط باشد، ولی اینگونه نیست. از اینجا به بعد، تمامی Hookهای بعد از Hookای که ما از رویش پریدیم یکی به بعدی منتقل می‌شود و منجر به باگ می‌گردد.</p>\n<p><strong>به همین دلیل است که Hookها باید در بالاترین سطح کامپوننت فراخوانی شوند.</strong> اگر بخواهیم Hookرا بر اساس شرطی اجرا کنیم می‌توانیم شرط را <em>درون</em> Hookمان قرار دهیم:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span> <span class=\"token function\">persistForm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// 👍 We're not breaking the first rule anymore</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>name <span class=\"token operator\">!==</span> <span class=\"token string\">''</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'formData'</span><span class=\"token punctuation\">,</span> name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><strong>توجه داشته باشید که اگر این پلاگین آستری که <a href=\"https://www.npmjs.com/package/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">فراهم</a> کردیم را نصب کنید دیگر نیاز نیست نگران این مشکلات باشید</strong> ولی الان می‌دانید که <em>چرا</em> Hookها اینگونه کار می‌کنند، و این قوانین از چه مشکلاتی جلوگیری می‌کند.</p>\n<h2 id=\"next-steps\"><a href=\"#next-steps\" 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>گام‌های بعدی </h2>\n<p>درنهایت، آماده هستیم تا در مورد <a href=\"/docs/hooks-custom.html\">نوشتن Hook شخصی خودمان</a> بیاموزیم! Hookهای شخصی اجازه می‌دهند تا چندین Hook که ری‌اکت فراهم کرده را باهم ترکیب کنید و انتزاع خود را داشته باشید، و از همان منطق stateful بین کامپوننت‌ها مجددا استفاده کنید.</p>","frontmatter":{"title":"Rules of Hooks","next":"hooks-custom.html","prev":"hooks-effect.html"},"fields":{"path":"content/docs/hooks-rules.md","slug":"docs/hooks-rules.html"}}},"pageContext":{"slug":"docs/hooks-rules.html"}},"staticQueryHashes":[]}