diff --git a/content/docs/hooks-intro.md b/content/docs/hooks-intro.md index 319002b24..ca91a6666 100644 --- a/content/docs/hooks-intro.md +++ b/content/docs/hooks-intro.md @@ -53,7 +53,7 @@ function Example() { **اگر هم‌‌اکنون می‌‌خواهید یادگیری هوک‌‌ها را شروع کنید، [مستقیم به صفحه‌‌ی بعد بروید!](/docs/hooks-overview.html)** البته می‌‌توانید مطالعه‌‌ این صفحه را ادامه دهید و با دلایلی که هوک‌‌ها را به ری‌‌اکت اضافه کردیم و اینکه چگونه بدون بازنویسی اپلیکیشن‌‌های قبلی از آن‌‌ها استفاده خواهیم کرد، آشنا شوید. -## انگیزه +## انگیزه {#انگیزه} هوک‌ها مشکلات مختلفی که ظاهرا به هم ارتباط ندارند را حل می‌کنند. مواردی که ما طی در نوشتن و نگهداری هزاران کامپوننت طی پنج سال با آن مواجه شده‌ایم. اگر درحال یادگیری ری‌اکت هستید، هروز از آن استفاده می‌کنید یا از کتابخانه مشابهی استفاده می‌کنید که بر پایه کامپوننت طراحی شده‌است، احتمالا به این مشکلات بر خورد کرده‌اید. diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index 24145eac2..2834d3e04 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -1,22 +1,23 @@ --- id: hooks-reference -title: Hooks API Reference +title: مرجع API هوک‌ها permalink: docs/hooks-reference.html prev: hooks-custom.html next: hooks-faq.html --- -*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. +*هوک‌ها* در نسخه‌ی 16.8 به ری‌اکت افزوده شدند. با استفاده از آنها شما می‌توانید از state و سایر ویژگی‌های ری‌اکت بدون نیاز به نوشتن کلاس استفاده کنید. -This page describes the APIs for the built-in Hooks in React. +در این صفحه شما تمام رابط‌های کاربری (API) برای هوک‌هایی که پیش-ساخته اند را خواهید یافت. -If you're new to Hooks, you might want to check out [the overview](/docs/hooks-overview.html) first. You may also find useful information in the [frequently asked questions](/docs/hooks-faq.html) section. +اگر تازه با هوک‌ها آشنا شده اید، شاید بهتر باشد اول از همه [مرور کلی](/docs/hooks-overview.html) آنها را بخوانید. همچنین در بخش [پاسخ به سوالات متداول](/docs/hooks-faq.html) هم اطلاعات مفیدی خواهید یافت. -- [Basic Hooks](#basic-hooks) + +- [هوک‌های اولیه](#basic-hooks) - [`useState`](#usestate) - [`useEffect`](#useeffect) - [`useContext`](#usecontext) -- [Additional Hooks](#additional-hooks) +- [هوک‌های دیگر](#additional-hooks) - [`useReducer`](#usereducer) - [`useCallback`](#usecallback) - [`useMemo`](#usememo) @@ -25,7 +26,7 @@ If you're new to Hooks, you might want to check out [the overview](/docs/hooks-o - [`useLayoutEffect`](#uselayouteffect) - [`useDebugValue`](#usedebugvalue) -## Basic Hooks {#basic-hooks} +## هوک‌های اولیه {#basic-hooks} ### `useState` {#usestate} @@ -33,25 +34,27 @@ If you're new to Hooks, you might want to check out [the overview](/docs/hooks-o const [state, setState] = useState(initialState); ``` -Returns a stateful value, and a function to update it. +این هوک، دو چیز را از خود باز می‌گرداند: یک متغیر برای state و یک تابع برای بروز رسانی همان متغیر. -During the initial render, the returned state (`state`) is the same as the value passed as the first argument (`initialState`). +اولین آرگومانی که برای یک هوک تعریف می‌کنید (`initialState`)، همان متغیری خواهد بود که در رندر اولیه، (`state`) شما خواهد شد. -The `setState` function is used to update the state. It accepts a new state value and enqueues a re-render of the component. +تابع `setState` برای به‌روز‌ رسانی آن متغیر استفاده می‌شود. می‌توان به آن متغیر جدیدی داد که باعث تغییر state شده و در نتیجه رندر مجدد آن کامپوننت را در صف اجرا قرار می‌دهد. ```js setState(newState); ``` +در رندر‌های بعدی، اولین متغیر بازگردانده شده از `useState` ، جدیدترین state آن کامپوننت بعد از به‌روز‌ رسانی خواهد بود. -During subsequent re-renders, the first value returned by `useState` will always be the most recent state after applying updates. ->Note +>توجه > ->React guarantees that `setState` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list. +>ری‌اکت تضمی‌ن می‌کند که تابع `setState` ماهیت خودش را در زمان رندرهای بعدی حفظ کند. از همی‌ن رو، با اطمی‌نان کامل می‌توان آن را از لیست وابستگی‌های `useEffect` و `useCallback` خارج کرد. + -#### Functional updates {#functional-updates} +#### به‌روز‌ رسانی از طریق تابع {#functional-updates} + +اگر state جدید با استفاده از `setState` قبلی محاسبه می‌شود، در آن صورت می‌توانید یک تابع را به عنوان آرگومان در setState وارد کنید. این تابع، متغیر پیشین برای state را دریافت خواهد کرد و متغیر به روز شده را خروجی خواهد داد. در مثال زیر، شما کامپوننتی را می‌بینید که کارش شمارش است و هر دو شکل تابع `setState` در آن استفاده شده است. -If the new state is computed using the previous state, you can pass a function to `setState`. The function will receive the previous value, and return an updated value. Here's an example of a counter component that uses both forms of `setState`: ```js function Counter({initialCount}) { @@ -67,24 +70,26 @@ function Counter({initialCount}) { } ``` -The "+" and "-" buttons use the functional form, because the updated value is based on the previous value. But the "Reset" button uses the normal form, because it always sets the count back to the initial value. +دکمه‌های “+” و “-“ از تابع به‌روز‌ رسانی متغیر state استفاده می‌کنند چون نیاز دارند از متغیر اولیه تعریف شده برای state باخبر شوند. اما دکمه ی “Reset” از شکل تابعی استفاده نمی‌کند چون همی‌شه متغیر را به آن مقداری که در ابتدا برایش تعریف شده بود باز می‌گرداند. + > Note > -> Unlike the `setState` method found in class components, `useState` does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax: +> هنگامی‌که در کامپوننت‌هایی که به شکل کلاس تعریف شده اند، از متد `setState` استفاده می‌کردید، می‌توانستید بخشی از آبجکتی که به عنوان متغیر state آن کامپوننت تعریف شده بود را عوض کنید و بقیه آبجکت دست نخورده باقی بماند. اما هنگام استفاده از `useState` این اتفاق به طور خودکار نمی‌افتد. اگر قصد دارید که بقیه آبجکت دست نخورده باقی بماند و فقط بخشی از آن را تغییر دهید، این را باید با استفاده از "تابع بروز کننده" و “object spread syntax” انجام دهید: > > ```js > setState(prevState => { -> // Object.assign would also work +> // همچنین می‌توان استفاده کرد از Object.assign > return {...prevState, ...updatedValues}; > }); > ``` > -> Another option is `useReducer`, which is more suited for managing state objects that contain multiple sub-values. +>یک راه دیگر برای محقق کردن این هدف، استفاده از `useReducer` است اما این روش برای به‌روز‌ رسانی آبجکت‌هایی مفید است که متغیرهای چند لایه و عمیق‌تری دارند. -#### Lazy initial state {#lazy-initial-state} +#### تعریف اولیه state از نوع کُند (Lazy initial state) {#lazy-initial-state} + +آرگومان `initialState` همان state است که در رندر اولیه استفاده می‌شود. اما در رندر‌های بعدی، ندیده گرفته می‌شود. اگر برای تولید متغیر state اولیه، نیاز به محاسبات سنگین دارید، می‌توانید آن را در یک تابع قرار دهید. این تابع فقط در رندر اولیه کامپوننت اجرا خواهد شد. -The `initialState` argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render: ```js const [state, setState] = useState(() => { @@ -93,11 +98,12 @@ const [state, setState] = useState(() => { }); ``` -#### Bailing out of a state update {#bailing-out-of-a-state-update} +#### انصراف دادن از به‌روز‌ رسانی state {#bailing-out-of-a-state-update} + +اگر متغیر استفاده شده در هوک state، پس از به‌روز‌ رسانی، هنچنان برابر با متغیر فعلی از آب در بیاید (یعنی تغییری نکرده باشد)، ری‌اکت از رندر مجدد فرزندان آن کامپوننت و اجرا کردن افکت‌ها (effects) اجتناب خواهد کرد. (ری‌اکت برای مقایسه از الگوریتم [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description) استفاده می‌کند.) -If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +دقت کنید که ممکن است ری‌اکت نیاز داشته باشد تا آن کامپوننت خاص را پیش از انصراف دادن، دوباره رندر کند. این مسئله جای نگرانی ندارد چون در آن صورت، بی دلیل وارد المنت‌هایی در لایه‌های عمیق‌تر نخواهد شد. اگر در حین رندر کردن محاسبات سنگین انجام می‌دهید، می‌توانید با استفاده از `useMemo` آنها را بهینه کنید. -Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. ### `useEffect` {#useeffect} @@ -105,45 +111,50 @@ Note that React may still need to render that specific component again before ba useEffect(didUpdate); ``` -Accepts a function that contains imperative, possibly effectful code. +یک تابع دریافت می‌کند. کدی که در تابع هست حالت دستوری داشته و احتمالا افکت ایجاد خواهد کرد. + +به فرآیندهایی نظیر تغییر داده‌ها، اشتراک داده‌ها (subscriptions)، تایمر‌ها، رخدادنگاری (logging) و از این قبیل، "اثرات جانبی" می‌گوییم. ری‌اکت کدی نوشته شده در بدنه ی یک کامپوننت از نوع تابعی را _فاز رندر_ می‌نامد. در این فاز، شما اجازه ندارید که اثرات جانبی داشته باشید. اگر اجازه ی این کار را داشتید باعث می‌شد که خطاهای سردرگم کننده ای بوجودآید و در نمایش رابط کاربری ناهماهنگی دیده شود. + +به جای آن، از `useEffect` استفاده کنید. تابعی که شما به `useEffect` می‌دهید زمانی اجرا می‌شود که رندر به صفحه ی نمایش ارسال شده باشد. می‌توانید اینگونه فرض کنید که استفاده از این افکت، به شما راه فراری می‌دهد تا از دنیای تابع گرایانه ی ری‌اکت خارج شوید و وارد دنیای برنامه نویسی دستوری شوید. -Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React's _render phase_). Doing so will lead to confusing bugs and inconsistencies in the UI. +به طور پیش فرض، افکت‌ها بعد از هر رندر فراخوانی می‌شوند، اما می‌توانید آنها را طوری تعریف کنید که فقط [در صورت تغییر بعضی از متغیر‌ها اجرا شوند](#conditionally-firing-an-effect). -Instead, use `useEffect`. The function passed to `useEffect` will run after the render is committed to the screen. Think of effects as an escape hatch from React's purely functional world into the imperative world. -By default, effects run after every completed render, but you can choose to fire it [only when certain values have changed](#conditionally-firing-an-effect). +#### پاکسازی یک افکت {#cleaning-up-an-effect} -#### Cleaning up an effect {#cleaning-up-an-effect} +غالبا افکت‌ها، منابعی از داده‌ها را ایجاد می‌کنند، اما پیش از آنکه کامپوننت ما از صفحه حذف شود، لازم است که این منابع را پاکسازی کنیم. به طور مثال اشتراک (subscription) و یا شناسه ی یک تایمر. برای پاکسازی آنها، می‌توانیم یک تابع را به عنوان خروجی `useEffect` استفاده کنیم که کار پاکسازی را برایمان انجام دهد. مثلا برای ایجاد یک اشتراک: -Often, effects create resources that need to be cleaned up before the component leaves the screen, such as a subscription or timer ID. To do this, the function passed to `useEffect` may return a clean-up function. For example, to create a subscription: ```js useEffect(() => { const subscription = props.source.subscribe(); return () => { - // Clean up the subscription + // اشتراک را پاک کن subscription.unsubscribe(); }; }); ``` -The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the **previous effect is cleaned up before executing the next effect**. In our example, this means a new subscription is created on every update. To avoid firing an effect on every update, refer to the next section. +برای آنکه دچار نشت در حافظه نشویم، تابعی که کار پاکسازی را انجام می‌دهد، پیش از آنکه کامپوننت ما از صفحه ی کاربر حذف شود اجرا خواهد شد. از طرف دیگر، اگر یک افکت چند بار فراخوانده شود (که معمولا این طور است)، **پیش از اجرای افکت بعدی، افکت پیشین پاکسازی خواهد شد.**این بدین معناست که در همی‌ن مثال قبلی ما، در هر به‌روز‌ رسانی یک اشتراک جدید خلق خواهد شد. برای جلوگیری از اجرای مکرر یک افکت در موقع به‌روز‌ رسانی، به قسمت بعدی مراجعه کنید. -#### Timing of effects {#timing-of-effects} -Unlike `componentDidMount` and `componentDidUpdate`, the function passed to `useEffect` fires **after** layout and paint, during a deferred event. This makes it suitable for the many common side effects, like setting up subscriptions and event handlers, because most types of work shouldn't block the browser from updating the screen. +#### زمان بندی افکت‌ها {#timing-of-effects} -However, not all effects can be deferred. For example, a DOM mutation that is visible to the user must fire synchronously before the next paint so that the user does not perceive a visual inconsistency. (The distinction is conceptually similar to passive versus active event listeners.) For these types of effects, React provides one additional Hook called [`useLayoutEffect`](#uselayouteffect). It has the same signature as `useEffect`, and only differs in when it is fired. +برخلاف `componentDidMount` و `componentDidUpdate`، تابعی که به `useEffect` می‌دهید، **پس از** صفحه آرایی (layout) و ترسیم (paint)، طی یک رویداد به تعویق افتاده (deferred event) اجرا می‌شود. از همی‌ن رو، useEffect مکان مناسبی برای اجرای بیشتر اثرات جانبی متدول است. مثل ایجاد اشتراک‌ها (subscriptions) و کنترل کننده ی رویداد‌ها (event handlers). دلیلش این است که بیشتر این کارها، نباید مانعی بر سر راه مرورگر در حین به‌روز‌ رسانی صفحه باشند. -Although `useEffect` is deferred until after the browser has painted, it's guaranteed to fire before any new renders. React will always flush a previous render's effects before starting a new update. +با این حال، نمی‌توان تمام افکت‌ها را با تعویق انجام داد. به طور مثال اگر تغییری که در DOM می‌دهیم در معرض دید کاربر باشد، باید آن را به طور همزمان (synchronously) و پیش از ترسیم صفحه انجام دهیم تا باعث بروز ناهماهنگی در صفحه ی نمایش نشود. (این از نظر مفهومی‌مانند تفاوت event listener‌های فعال و غیرفعال است.) برای اعمال چنین افکت‌هایی، ری‌اکت هوک دیگری را در اختیار شما قرار می‌دهد: [`useLayoutEffect`](#uselayouteffect). این افکت کارکردی شبیه `useEffect` دارد و تنها تفاوتش زمان اجرای آن است. -#### Conditionally firing an effect {#conditionally-firing-an-effect} +برخلاف آنکه اجرای `useEffect` تا پس از ترسیم صفحه به تعویق می‌افتد، اما قطعا پیش از رندر‌های جدید اجرا خواهد شد. ری‌اکت همی‌شه افکت‌های متعلق به رندر پیشین را قبل از به‌روز‌ رسانی جدید، اعمال کرده و تمام می‌کند. -The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its dependencies changes. -However, this may be overkill in some cases, like the subscription example from the previous section. We don't need to create a new subscription on every update, only if the `source` props has changed. +#### اجرای مشروط یک افکت {#conditionally-firing-an-effect} + +رفتار پیش فرض افکت‌ها بدین شکل است که پس از اتمام هر رندر، فراخوانی و اجرا شوند. در این حالت، اگر یکی از وابستگی‌های افکت ما تغییر کند، افکت دوباره اجرا می‌شود. + +اما این در بعضی از موارد ممکن است باعث افراط بی مورد شود. مثال قبلی که در مورد ایجاد اشتراک (subscription) بود را به خاطر بیاورید. ما نیاز نداریم که در هر به‌روز‌ رسانی، یک اشتراک جدید بسازیم. مگر آنکه props‌هایی که دریافت می‌کنیم تغییر کرده باشند. + +بدین منظور، آرگومان دومی‌را به `useEffect` بدهید. این آرگومان یک آرایه (array) خواهد بود شامل تمام متغیرهایی که افکت ما به آن وابسته است. مثال قبلی ما پس از به‌روز‌ رسانی بدین شکل در خواهد آمد: -To implement this, pass a second argument to `useEffect` that is the array of values that the effect depends on. Our updated example now looks like this: ```js useEffect( @@ -157,20 +168,18 @@ useEffect( ); ``` -Now the subscription will only be recreated when `props.source` changes. - ->Note +>توجه > ->If you use this optimization, make sure the array includes **all values from the component scope (such as props and state) that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and what to do when the [array values change too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often). +>اگر خواستید این بهینه سازی را انجام دهید، اول اطمی‌نان حاصل کنید که **تمام متغیر‌هایی که در حوزه ی کامپوننت هستند (از قبیل state و props‌ها) که در طول زمان عوض می‌شوند و افکت از آنها استفاده می‌کند**، در آرایه اضافه کرده اید. در غیر این صورت، کد شما از متغیرهای مرده ای که از رندر‌های پیشین به جای مانده اند استفاده خواهد کرد. یاد بگیرید که [چگونه با توابع کار کنید](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) و زمانی که [آرایه متغیرها مکررا تغییر می‌کند](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often)، چه کنید. > ->If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the dependencies array always works. +>اگر شما می‌خواهید که یک افکت فقط یک بار اجرا و پاکسازی شود (در mount و unmount)، می‌توانید به عنوان آرگومان دوم یک آرایه ی خالی (`[]`) وارد کنید. با این کار به ری‌اکت می‌گویید که افکت شما هیچ وابستگی به متغیرهای state یا props ندارد. پس لازم نیست که مجددا اجرا شود. البته این یک حالت ویژه نیست – آرایه ی وابستگی‌ها همی‌شه اینطور کار می‌کنند. > ->If you pass an empty array (`[]`), the props and state as inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem. +>وقتی که یک آرایه ی خالی (`[]`) به آن می‌دهید، state و props شما، در درون افکت، همی‌شه معادل اولین ارزشی خواهند بود که برایشان تعریف کرده بودید. دادن `[]` به عنوان آرگومان دوم یک افکت، شاید نزدیک‌ترین چیز به مدل `componentDidMount` و `componentWillUnmount` باشد، اما معمولا [راه‌های ](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [بهتری](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) هست که با استفاده از آنها بتوان مانع از رندر شدن مکرر شد. از سوی دیگر فراموش نکنید که ری‌اکت اجرای useEffect را تا زمانی که مرورگر ترسیم صفحه را تمام نکرده باشد به تعویق می‌اندازد، در نتیجه انجام این کارهای اضافی، مشکلات کمتری درست می‌کند. > -> ->We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. +>توصیه می‌کنیم که از قانون [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) که بخشی از پکیج [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) می‌باشد استفاده کنید. اگر وابستگی‌ها به شکل نادرستی اعلام شده باشند، به شما هشدار داده و راه اصلاحش را پیشنهاد می‌دهد. + +آرایه ی حاوی وابستگی‌ها، مستقیما به عنوان یک آرگومان در خود تابع افکت‌ها وارد نمی‌شود. اما به طور منطقی، کارش همی‌ن است: هر متغیری که داخل تابع افکت از آن استفاده شده، باید در آرایه ی وابستگی‌های آن افکت هم حضور داشته باشد. در آینده، کامپایلری که به اندازه کافی پیشرفته باشد قادر خواهد بود تا این آرایه ی وابستگی‌ها را به طور خودکار بسازد. -The array of dependencies is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. ### `useContext` {#usecontext} @@ -178,27 +187,28 @@ The array of dependencies is not passed as arguments to the effect function. Con const value = useContext(MyContext); ``` -Accepts a context object (the value returned from `React.createContext`) and returns the current context value for that context. The current context value is determined by the `value` prop of the nearest `` above the calling component in the tree. +این هوک، آبجکت context را دریافت می‌کند (همان متغیری که از `React.createContext` بازگردانده می‌شود) و بعد value مرتبط با context فعلی را به ما می‌دهد. اما محتویات داخل context فعلی ما از کجا می‌آیند؟ از نزدیک‌ترین`` به ما، (فوق همی‌ن کامپوننت)، که در خودش یک prop با عنوان `value` داشته باشد. -When the nearest `` above the component updates, this Hook will trigger a rerender with the latest context `value` passed to that `MyContext` provider. +وقتی که نزدیک‌ترین `` ، بالای یک کامپوننت به روز رسانی می‌شود، این هوک فرایند رندر کردن مجدد کامپوننت را کلید می‌زند و برای این کار از جدیدترین `value` که به `` داده شده است استفاده می‌کند. -Don't forget that the argument to `useContext` must be the *context object itself*: +فراموش نکنید آرگومانی که به `useContext` می‌دهید باید *خود آبجکت context* باشد. - * **Correct:** `useContext(MyContext)` - * **Incorrect:** `useContext(MyContext.Consumer)` - * **Incorrect:** `useContext(MyContext.Provider)` + * **صحیح:** `useContext(MyContext)` + * **نادرست:** `useContext(MyContext.Consumer)` + * **نادرست:** `useContext(MyContext.Provider)` -A component calling `useContext` will always re-render when the context value changes. If re-rendering the component is expensive, you can [optimize it by using memoization](https://github.com/facebook/react/issues/15156#issuecomment-474590693). +اگر متغیرهای context عوض شوند، کامپوننتی که هوک `useContext` را فراخوانی کرده، مجددا رندر خواهدشد. اگر رندر مجدد یک کامپوننت پرهزینه است، [با استفاده از memoization آن را بهینه کنید.](https://github.com/facebook/react/issues/15156#issuecomment-474590693) ->Tip +>نکته > ->If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to ``. +>اگر شما پیشتر با context API که پیش از معرفی هوک‌ها بوده کار کرده باشید، کاری که هوک `useContext(MyContext)` می‌کند دقیقا معادل `static contextType = MyContext` است که در کلاس انجام می‌دادیم و یا ``. > ->`useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `` above in the tree to *provide* the value for this context. +>`useContext(MyContext)`فقط این امکان را به شما می‌دهد که context را *بخوانید* و مشترک تغییراتش شوید. شما همچنان نیازمند یک `` در شاخه‌های بالایی هستید که value لازم برای context را تولید کند. -## Additional Hooks {#additional-hooks} -The following Hooks are either variants of the basic ones from the previous section, or only needed for specific edge cases. Don't stress about learning them up front. +## هوک‌های دیگر {#additional-hooks} + +هوک‌هایی که در ادامه می‌آیند، گونه ی دیگری از هوک‌های اولیه هستند که در بخش قبل توضیح دادیم، و یا در موارد خاص کاربرد پیدا می‌کنند. تا زمانی که ضرورتش پیش نیامده، خودتان را درگیر یادگیری آنها نکنید. ### `useReducer` {#usereducer} @@ -206,11 +216,11 @@ The following Hooks are either variants of the basic ones from the previous sect const [state, dispatch] = useReducer(reducer, initialArg, init); ``` -An alternative to [`useState`](#usestate). Accepts a reducer of type `(state, action) => newState`, and returns the current state paired with a `dispatch` method. (If you're familiar with Redux, you already know how this works.) +این جایگزینی برای [`useState`](#usestate) می‌تواند باشد. یک reducer از نوع `(state, action) => newState` می‌گیرد و خروجی که به شما می‌دهد state فعلی است به همراه متد `dispatch` . (اگر با ریداکس Redux آشنا باشید می‌دانید که شیوه ی کارش چیست.) -`useReducer` is usually preferable to `useState` when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. `useReducer` also lets you optimize performance for components that trigger deep updates because [you can pass `dispatch` down instead of callbacks](/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down). +اما چه زمانی بهتر است به جای `useState` از `useReducer` استفاده کنید؟ زمانی که state شما ساختار منطقی پیچیده ای دارد و شامل زیر مجموعه‌هایی با عضو‌های متعدد است، یا زمانی که state بعدی شما وابسته به state پیشین شما است. بعلاوه اگر کامپوننت‌هایی دارید که به‌روز‌ رسانی در لایه‌های عمیق‌تری انجام می‌دهند، `useReducer` به شما این امکان را می‌دهد تا این فرایند را بهینه کنید [چون قادر خواهید بود که به جای کال بک‌ها (callbacks)، از `dispatch` استفاده کنید.](/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down) -Here's the counter example from the [`useState`](#usestate) section, rewritten to use a reducer: +در ادامه، مثال شمارشگر قبلی را که پیشتر با [`useState`](#usestate) نوشته بودیم را با reducer بازنویسی می‌کنیم: ```js const initialState = {count: 0}; @@ -238,13 +248,14 @@ function Counter({initialState}) { } ``` ->Note +>توجه > ->React guarantees that `dispatch` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list. +>ری‌اکت این اطمی‌نان را می‌دهند که ماهیت تابع `dispatch` ثابت بماند و در رندر‌های بعدی عوض نشود. در نتیجه، با خیال راحت می‌توان آن را از لیست وابستگی‌های `useEffect` و `useCallback` حذف کرد. + -#### Specifying the initial state {#specifying-the-initial-state} +#### تعریف کردن state اولیه {#specifying-the-initial-state} -There’s two different ways to initialize `useReducer` state. You may choose either one depending on the use case. The simplest way to pass the initial state as a second argument: +به 2 طریق متفاوت می‌توان state اولیه در `useReducer` را تعریف کرد. بسته به شرایط از هر کدام که خواستید می‌توانید استفاده کنید. ساده‌ترین راه، دادن آن به عنوان آرگومان دوم است: ```js{3} const [state, dispatch] = useReducer( @@ -253,15 +264,15 @@ There’s two different ways to initialize `useReducer` state. You may choose ei ); ``` ->Note +>توجه > ->React doesn’t use the `state = initialState` argument convention popularized by Redux. The initial value sometimes needs to depend on props and so is specified from the Hook call instead. If you feel strongly about this, you can call `useReducer(reducer, undefined, reducer)` to emulate the Redux behavior, but it's not encouraged. +>شیوه ای که توسط ریداکس برای دادن آرگومان باب شده، `state = initialState` می‌باشد، اما ری‌اکت از این شیوه استفاده نمی‌کند. چون متغیر اولیه ما بعضی از اوقات وابسته به props است و از هوک فراخوانی می‌شود. اگر همچنان نظر متفاوتی دارید می‌توانید آرگومان‌های خود را به شکل زیر وارد کنید تا عملکردی مانند ریداکس داشته باشد: `useReducer(reducer, undefined, reducer)` -#### Lazy initialization {#lazy-initialization} +#### تعریف اولیه از نوع کُند (Lazy initialization) {#lazy-initialization} -You can also create the initial state lazily. To do this, you can pass an `init` function as the third argument. The initial state will be set to `init(initialArg)`. +شما می‌توانید state اولیه را کندتر تعریف کنید. برای این کار، کافی است تابع `init` را به عنوان آرگومان سوم به useReducer بدهید. در این حالت، state اولیه ی ما برابر `init(initialArg)` خواهد بود. -It lets you extract the logic for calculating the initial state outside the reducer. This is also handy for resetting the state later in response to an action: +با این کار، شما کدی که برای محاسبه ی state اولیه وجود دارد را از توی reducer در می‌آورید. بعدها، وقتی که بخواهید state را در پاسخ به یک رویداد ریست کنید، این به درد خواهد خورد. ```js{1-3,11-12,19,24} function init(initialCount) { @@ -297,11 +308,11 @@ function Counter({initialCount}) { } ``` -#### Bailing out of a dispatch {#bailing-out-of-a-dispatch} +#### انصراف دادن از dispatch {#bailing-out-of-a-dispatch} -If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +اگر متغیر خروجی شما از هوک Reducer همچنان برابر با state فعلی از آب در بیاید(یعنی تغییری نکرده باشد)، ری‌اکت از رندر مجدد فرزندان آن کامپوننت و اجرا کردن افکت‌ها (effects) اجتناب خواهد کرد. (ری‌اکت برای مقایسه از الگوریتم [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description) استفاده می‌کند.) -Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. +دقت کنید که ممکن است ری‌اکت نیاز داشته باشد تا آن کامپوننت خاص را پیش از انصراف دادن، دوباره رندر کند. این نباید موجب نگرانی باشد چون در آن صورت، بدون دلیل وارد المنت‌ها در لایه‌های عمیق‌تر نخواهد شد. اگر در حین رندر کردن محاسبات سنگین انجام می‌شود، می‌توانید با استفاده از `useMemo` آنها را بهینه کنید. ### `useCallback` {#usecallback} @@ -314,17 +325,23 @@ const memoizedCallback = useCallback( ); ``` -Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) callback. +یک کال بک مموایز شده ([memoized](https://en.wikipedia.org/wiki/Memoization) callback) را باز می‌گرداند. -Pass an inline callback and an array of dependencies. `useCallback` will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`). +یک کال بک اینلاین و آرایه ای از وابستگی‌ها را به آن بدهید. `useCallback` نسخه ی مموایز شده ای از کال بک را به شما باز خواهد گرداند. این نسخه فقط زمانی تغییر خواهد کرد که یکی از وابستگی‌هایش تغییر کند. این در چه مواقعی به درد می‌خورد؟ زمانی که می‌خواهیم کال بک‌ها را به کامپوننت‌های سطح پایینی بدهیم که بهینه شده اند. این کامپوننت‌ها با تکیه بر "برابری و تطبیق متغیر با مرجعش" از رندر‌های بی مورد جلوگیری می‌کنند (به طور مثال: `shouldComponentUpdate`). -`useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`. +هر دو کدی که در زیر می‌بینید، کار یکسانی را انجام می‌دهند: -> Note +`useCallback(آرایه ی وابستگیها، تابع)` + +`useMemo(() => آرایه ی وابستگیها، تابع)` + + +> توجه > -> The array of dependencies is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. +>آرایه ی حاوی وابستگی‌ها، مستقیما به عنوان آرگومان به خود کال بک‌ها داده نمی‌شود. اما به طور منطقی، کارشان همی‌ن است: هر متغیری که داخل کال بک ذکر شده، باید در آرایه ی وابستگی‌های آن هم حضور داشته باشد. در آینده، کامپایلری که به اندازه کافی پیشرفته باشد قادر خواهد بود تا این آرایه ی وابستگی‌ها را به طور خودکار بسازد. > -> We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. +>توصیه می‌کنیم که از قانون [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) که بخشی از پکیج [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) می‌باشد استفاده کنید. اگر وابستگی‌ها به شکل نادرستی اعلام شده باشند، به شما هشدار داده و راه اصلاحش را پیشنهاد می‌دهد. + ### `useMemo` {#usememo} @@ -332,21 +349,22 @@ Pass an inline callback and an array of dependencies. `useCallback` will return const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` -Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) value. +یک متغیر [مموایز ](https://en.wikipedia.org/wiki/Memoization)شده را باز می‌گرداند. -Pass a "create" function and an array of dependencies. `useMemo` will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render. +به آن یک تابع می‌دهید که نقش تولید کننده را دارد و آرگومان بعدیش، آرایه ای متشکل از وابستگی‌هاست. فقط زمانی `useMemo` محاسبه مجدد را شروع می‌کند که یکی از وابستگی‌هایش تغییر کرده باشد. با این بهینه سازی، جلوی محاسبات سنگینی که در هر رندر می‌تواند روی دهد را می‌گیریم. -Remember that the function passed to `useMemo` runs during rendering. Don't do anything there that you wouldn't normally do while rendering. For example, side effects belong in `useEffect`, not `useMemo`. +فراموش نکنید تابعی که به `useMemo` داده می‌شود، در زمان رندر، اجرا خواهد شد. در آن تابع نباید کاری انجام دهید که به طور معمول در حین رندر انجام نمی‌شود. به طور مثال، "اثرات جانبی" جایشان در `useEffect` است و نه در `useMemo`. -If no array is provided, a new value will be computed on every render. +اگر آرایه ای به آن نداده باشید، ارزش آن متغیر در هر رندر مجددا محاسبه خواهد شد. -**You may rely on `useMemo` as a performance optimization, not as a semantic guarantee.** In the future, React may choose to "forget" some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without `useMemo` — and then add it to optimize performance. +**شما می‌توانید به `useMemo` برای بهینه سازی اجرا و نمایش کامپوننت تکیه کنید، اما نه به عنوان چیزی که همی‌شه به یک شکل کار کند.** مثلا در آینده ممکن است ری‌اکت برای کامپوننت‌هایی که هنوز نمایش داده نشده اند، نیاز به آزاد کردن فضا در حافظه داشته باشد و بخاطر همی‌ن، ممکن است متغیر مموایز شده ی پیشین را فراموش کند و در رندر بعدی دوباره آن را محاسبه کند. کدتان را جوری بنویسید که بدون `useMemo` هم درست کار کند و از آن صرفا برای بهینه سازی اجرای کد استفاده کنید. -> Note + +> توجه > -> The array of dependencies is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. +> آرایه ی حاوی وابستگی‌ها، مستقیما به عنوان آرگومان به خود تابع داده نمی‌شود. اما به طور منطقی، کارشان همی‌ن است: هر متغیری که داخل تابع ذکر شده، باید در آرایه ی وابستگی‌های آن هم حضور داشته باشد. در آینده، کامپایلری که به اندازه کافی پیشرفته باشد قادر خواهد بود تا این آرایه ی وابستگی‌ها را به طور خودکار بسازد. > -> We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. +> توصیه می‌کنیم که از قانون [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) که بخشی از پکیج [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) می‌باشد استفاده کنید. اگر وابستگی‌ها به شکل نادرستی اعلام شده باشند، به شما هشدار داده و راه اصلاحش را پیشنهاد می‌دهد. ### `useRef` {#useref} @@ -354,9 +372,9 @@ If no array is provided, a new value will be computed on every render. const refContainer = useRef(initialValue); ``` -`useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component. +`useRef` یک آبجکت قابل رجوع (ref object) به شما می‌دهد که اولا متغیرهایش می‌توانند تغییر کنند و ثانیا پراپرتی .`.current` آن برابر با آرگومان (`initialValue`) خواهد بود. آبجکتی که به شما باز می‌گرداند، تا پایان طول عمر کامپوننت دوام خواهد داشت. -A common use case is to access a child imperatively: +یک استفاده ی متداول آن، برای دسترسی به المنت‌های زیرین، به شکل دستوری است: ```js function TextInputWithFocusButton() { @@ -374,15 +392,18 @@ function TextInputWithFocusButton() { } ``` -Essentially, `useRef` is like a "box" that can hold a mutable value in its `.current` property. +به عبارت دیگر، `useRef` مانند ظرفی است که قادر است یک متغیر قابل تغییر را داخل پراپرتی `.current` خودش نگه دارد. + +ممکن است آشنایی شما با refs بیشتر در حوزه ی [دسترسی به DOM ](/docs/refs-and-the-dom.html)بوده باشد. اگر شما به شکل زیر یک آبجکت قابل ارجاع به ری‌اکت بدهید: +`
` +آن وقت هر زمانی که نود مربوط به آن در DOM تغییر کند، ری‌اکت پراپرتی `.current` آن را برابر همان خواهد ساخت. -You might be familiar with refs primarily as a way to [access the DOM](/docs/refs-and-the-dom.html). If you pass a ref object to React with `
`, React will set its `.current` property to the corresponding DOM node whenever that node changes. +با این همه، کاربرد `useRef()` بیشتر از صفت ref آن است. چون وقتی بخواهید [متغیری را که ارزشش ممکن است عوض شود را دم دست نگه دارید](/docs/hooks-faq.html#is-there-something-like-instance-variables)، به راحتی به کارتان خواهد آمد. همانند زمانی که از instance fields در کلاس‌ها استفاده می‌کردید. -However, `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. -This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that `useRef` will give you the same ref object on every render. +این امکان به این دلیل بوجود می‌آید که `useRef()` یک آبجکت معمولی جاوااسکریپت می‌سازد. شاید بپرسید اگر خودتان یک آبجکت به شکل `{current: ...}` بسازید، این چه فرقی با `useRef()` خواهد داشت؟ تفاوتش این است که `useRef` در هر رندر، همان آبجکت ref شده را به شما خواهد داد. -Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutating the `.current` property doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) instead. +دقت کنید زمانی که محتویات `useRef` عوض شود، او به شما *خبر نخواهد داد*. عوض کردن پراپرتی .`.current` آن، موجب رندر مجدد نمی‌شود. اگر مایلید که هنگام وصل کردن یا جدا کردن یک ref به نودی در DOM، کدی را ری‌اکت اجرا کند، بهتر است از [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) به جای این استفاده کنید. ### `useImperativeHandle` {#useimperativehandle} @@ -391,7 +412,8 @@ Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutati useImperativeHandle(ref, createHandle, [deps]) ``` -`useImperativeHandle` customizes the instance value that is exposed to parent components when using `ref`. As always, imperative code using refs should be avoided in most cases. `useImperativeHandle` should be used with `forwardRef`: +وقتی که از `ref` در کامپوننتی استفاده می‌کنید، `useImperativeHandle` به شما اجازه می‌دهد تا متغیر آن را از طریق کامپوننت والدش دستکاری کنید. مثل همی‌شه اکثرا باید از کد کردن دستوری، که از refs استفاده می‌کند، اجتناب کرد. `useImperativeHandle` باید با `forwardRef` استفاده شود: + ```js function FancyInput(props, ref) { @@ -406,21 +428,30 @@ function FancyInput(props, ref) { FancyInput = forwardRef(FancyInput); ``` -In this example, a parent component that renders `` would be able to call `fancyInputRef.current.focus()`. +در این مثال، کامپوننت والدی که `` را رندر می‌کند، قادر خواهد بود که `fancyInputRef.current.focus()` را فراخوانی کند. + ### `useLayoutEffect` {#uselayouteffect} -The signature is identical to `useEffect`, but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint. +این مشابه `useEffect` است، با این تفاوت که به طور همزمان (synchronously) پس از اعمال تمام تغییرات در DOM اجرا می‌شود. با استفاده از آن قادر خواهید بود که آرایش صفحه را از DOM بخوانید و به طور همزمان رندر مجدد کنید. به‌روز‌ رسانی‌هایی که درون `useLayoutEffect` نوشته شده باشند، به طور همزمان اجرا و تمام خواهند شد، پیش از آنکه مرورگر، ترسیم صفحه را شروع کرده باشد. -Prefer the standard `useEffect` when possible to avoid blocking visual updates. +ترجیحا تا حد امکان از `useEffect` استفاده کنید تا در راه به‌روز‌ رسانی بصری مانع ایجاد نکنید. -> Tip + +> نکته +> +>اگر در حال تبدیل کامپوننت‌های کلاس خود هستید، توجه کنید که `useLayoutEffect` در همان فازی کلید می‌خورد که `componentDidMount` و `componentDidUpdate` کلید می‌خورند. با این حال **توصیه ما این است که اول از همه با `useEffect` شروع کنید** و بعد اگر با مشکل روبرو شدید، `useLayoutEffect` را استفاده کنید. > -> If you're migrating code from a class component, note `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`. However, **we recommend starting with `useEffect` first** and only trying `useLayoutEffect` if that causes a problem. +>اگر رندر شما در سرور انجام می‌شود، به خاطر داشته باشید که `useLayoutEffect` یا `useEffect` تا زمانی که تمام کد جاوااسکریپت دانلود نشده باشد اجرا نخواهد شد. به همی‌ن دلیل است که ری‌اکت زمانی که کامپوننتی در سرور رندر می‌شود و حاوی `useLayoutEffect` است به شما هشدار می‌دهد. برای حل این مشکل، دو راه دارید: یک راه این است که اگر کد شما در اولین رندر دخالتی ندارد، آن را به درون `useEffect` انتقال دهید. اما اگر بدون اجرای `useLayoutEffect` ، HTML شما خراب به نظر می‌رسد، نمایش آن کامپوننت را تا زمانی که صفحه ی کاربر رندر نشده باشد به تاخیر بیندازید. > ->If you use server rendering, keep in mind that *neither* `useLayoutEffect` nor `useEffect` can run until the JavaScript is downloaded. This is why React warns when a server-rendered component contains `useLayoutEffect`. To fix this, either move that logic to `useEffect` (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until `useLayoutEffect` runs). +>برای جدا کردن کامپوننتی که به افکت‌های صفحه آرایی نیاز دارد و از سرور رندر می‌شود، آن را به طور مشروط رندر کنید: +>`showChild && ` > ->To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with `showChild && ` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn't appear broken before hydration. +>و بعد به شکل زیر، نمایش آن را به تعویق بیندازید: +>`useEffect(() => { setShowChild(true); }, [])` +> +>با این کار، صفحه ی رابط کاربری شما دچار اختلال در نمایش نخواهد شد. + ### `useDebugValue` {#usedebugvalue} @@ -428,9 +459,9 @@ Prefer the standard `useEffect` when possible to avoid blocking visual updates. useDebugValue(value) ``` -`useDebugValue` can be used to display a label for custom hooks in React DevTools. +`useDebugValue` برای این استفاده می‌شود که برای هوک‌های سفارشی (custom hooks) برچسبی درست کنید تا در React DevTools نمایش داده شود. -For example, consider the `useFriendStatus` custom Hook described in ["Building Your Own Hooks"](/docs/hooks-custom.html): +به طور مثال `useFriendStatus` یک هوک سفارشی بود که در ["ساختن هوک‌های خودتان"](/docs/hooks-custom.html) ساخته بودیم: ```js{6-8} function useFriendStatus(friendID) { @@ -438,25 +469,26 @@ function useFriendStatus(friendID) { // ... - // Show a label in DevTools next to this Hook - // e.g. "FriendStatus: Online" + // کنار این هوک، برچسبی را نمایش بده در DevTools + // مثلا: "FriendStatus: Online" useDebugValue(isOnline ? 'Online' : 'Offline'); return isOnline; } ``` -> Tip +> نکته > -> We don't recommend adding debug values to every custom Hook. It's most valuable for custom Hooks that are part of shared libraries. +> ما توصیه نمی‌کنیم که برای تمام هوک‌های سفارشی متغیرهایی برای خطایابی اضافه کنید. این قابلیت بیش از همه برای آن هوک‌های سفارشی مفید است که بخشی از کتابخانه‌های به اشتراک گذاشته شده باشند. + +#### فرمت کردن متغیر خطایابی را به تاخیر بیندازید {#defer-formatting-debug-values} -#### Defer formatting debug values {#defer-formatting-debug-values} +در بعضی مواقع، فرمت کردن یک متغیر برای مشاهده ی بهترش، می‌تواند عملیات پرهزینه ای باشد. -In some cases formatting a value for display might be an expensive operation. It's also unnecessary unless a Hook is actually inspected. +از همی‌ن روی، `useDebugValue` یک تابع برای فرمت کردن را به عنوان آرگومان اختیاری دوم می‌تواند بپذیرد. این تابع فقط زمانی فراخوانده می‌شود که هوک مورد نظر تحت بررسی قرار گیرد. این تابع، متغیر خطایابی را (به عنوان آرگومانش) دریافت می‌کند و شکل فرمت شده ی آن را باز می‌گرداند. -For this reason `useDebugValue` accepts a formatting function as an optional second parameter. This function is only called if the Hooks are inspected. It receives the debug value as a parameter and should return a formatted display value. +فرض کنیم که در یک هوک سفارشی، متغیری از جنس زمان (`Date`) بازگردانده می‌شود. برای اینکه بی مورد از تابع `toDateString` استفاده نشود، می‌توانید آن را به عنوان تابع فرمت کننده به `useDebugValue` بدهید: -For example a custom Hook that returned a `Date` value could avoid calling the `toDateString` function unnecessarily by passing the following formatter: ```js useDebugValue(date, date => date.toDateString()); diff --git a/content/docs/reference-events.md b/content/docs/reference-events.md index 745c6a71e..e69de29bb 100644 --- a/content/docs/reference-events.md +++ b/content/docs/reference-events.md @@ -1,389 +0,0 @@ ---- -id: events -title: SyntheticEvent -permalink: docs/events.html -layout: docs -category: Reference ---- - -This reference guide documents the `SyntheticEvent` wrapper that forms part of React's Event System. See the [Handling Events](/docs/handling-events.html) guide to learn more. - -## Overview {#overview} - -Your event handlers will be passed instances of `SyntheticEvent`, a cross-browser wrapper around the browser's native event. It has the same interface as the browser's native event, including `stopPropagation()` and `preventDefault()`, except the events work identically across all browsers. - -If you find that you need the underlying browser event for some reason, simply use the `nativeEvent` attribute to get it. Every `SyntheticEvent` object has the following attributes: - -```javascript -boolean bubbles -boolean cancelable -DOMEventTarget currentTarget -boolean defaultPrevented -number eventPhase -boolean isTrusted -DOMEvent nativeEvent -void preventDefault() -boolean isDefaultPrevented() -void stopPropagation() -boolean isPropagationStopped() -DOMEventTarget target -number timeStamp -string type -``` - -> Note: -> -> As of v0.14, returning `false` from an event handler will no longer stop event propagation. Instead, `e.stopPropagation()` or `e.preventDefault()` should be triggered manually, as appropriate. - -### Event Pooling {#event-pooling} - -The `SyntheticEvent` is pooled. This means that the `SyntheticEvent` object will be reused and all properties will be nullified after the event callback has been invoked. -This is for performance reasons. -As such, you cannot access the event in an asynchronous way. - -```javascript -function onClick(event) { - console.log(event); // => nullified object. - console.log(event.type); // => "click" - const eventType = event.type; // => "click" - - setTimeout(function() { - console.log(event.type); // => null - console.log(eventType); // => "click" - }, 0); - - // Won't work. this.state.clickEvent will only contain null values. - this.setState({clickEvent: event}); - - // You can still export event properties. - this.setState({eventType: event.type}); -} -``` - -> Note: -> -> If you want to access the event properties in an asynchronous way, you should call `event.persist()` on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code. - -## Supported Events {#supported-events} - -React normalizes events so that they have consistent properties across different browsers. - -The event handlers below are triggered by an event in the bubbling phase. To register an event handler for the capture phase, append `Capture` to the event name; for example, instead of using `onClick`, you would use `onClickCapture` to handle the click event in the capture phase. - -- [Clipboard Events](#clipboard-events) -- [Composition Events](#composition-events) -- [Keyboard Events](#keyboard-events) -- [Focus Events](#focus-events) -- [Form Events](#form-events) -- [Mouse Events](#mouse-events) -- [Pointer Events](#pointer-events) -- [Selection Events](#selection-events) -- [Touch Events](#touch-events) -- [UI Events](#ui-events) -- [Wheel Events](#wheel-events) -- [Media Events](#media-events) -- [Image Events](#image-events) -- [Animation Events](#animation-events) -- [Transition Events](#transition-events) -- [Other Events](#other-events) - -* * * - -## Reference {#reference} - -### Clipboard Events {#clipboard-events} - -Event names: - -``` -onCopy onCut onPaste -``` - -Properties: - -```javascript -DOMDataTransfer clipboardData -``` - -* * * - -### Composition Events {#composition-events} - -Event names: - -``` -onCompositionEnd onCompositionStart onCompositionUpdate -``` - -Properties: - -```javascript -string data - -``` - -* * * - -### Keyboard Events {#keyboard-events} - -Event names: - -``` -onKeyDown onKeyPress onKeyUp -``` - -Properties: - -```javascript -boolean altKey -number charCode -boolean ctrlKey -boolean getModifierState(key) -string key -number keyCode -string locale -number location -boolean metaKey -boolean repeat -boolean shiftKey -number which -``` - -The `key` property can take any of the values documented in the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). - -* * * - -### Focus Events {#focus-events} - -Event names: - -``` -onFocus onBlur -``` - -These focus events work on all elements in the React DOM, not just form elements. - -Properties: - -```javascript -DOMEventTarget relatedTarget -``` - -* * * - -### Form Events {#form-events} - -Event names: - -``` -onChange onInput onInvalid onSubmit -``` - -For more information about the onChange event, see [Forms](/docs/forms.html). - -* * * - -### Mouse Events {#mouse-events} - -Event names: - -``` -onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit -onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave -onMouseMove onMouseOut onMouseOver onMouseUp -``` - -The `onMouseEnter` and `onMouseLeave` events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase. - -Properties: - -```javascript -boolean altKey -number button -number buttons -number clientX -number clientY -boolean ctrlKey -boolean getModifierState(key) -boolean metaKey -number pageX -number pageY -DOMEventTarget relatedTarget -number screenX -number screenY -boolean shiftKey -``` - -* * * - -### Pointer Events {#pointer-events} - -Event names: - -``` -onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture -onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut -``` - -The `onPointerEnter` and `onPointerLeave` events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase. - -Properties: - -As defined in the [W3 spec](https://www.w3.org/TR/pointerevents/), pointer events extend [Mouse Events](#mouse-events) with the following properties: - -```javascript -number pointerId -number width -number height -number pressure -number tangentialPressure -number tiltX -number tiltY -number twist -string pointerType -boolean isPrimary -``` - -A note on cross-browser support: - -Pointer events are not yet supported in every browser (at the time of writing this article, supported browsers include: Chrome, Firefox, Edge, and Internet Explorer). React deliberately does not polyfill support for other browsers because a standard-conform polyfill would significantly increase the bundle size of `react-dom`. - -If your application requires pointer events, we recommend adding a third party pointer event polyfill. - -* * * - -### Selection Events {#selection-events} - -Event names: - -``` -onSelect -``` - -* * * - -### Touch Events {#touch-events} - -Event names: - -``` -onTouchCancel onTouchEnd onTouchMove onTouchStart -``` - -Properties: - -```javascript -boolean altKey -DOMTouchList changedTouches -boolean ctrlKey -boolean getModifierState(key) -boolean metaKey -boolean shiftKey -DOMTouchList targetTouches -DOMTouchList touches -``` - -* * * - -### UI Events {#ui-events} - -Event names: - -``` -onScroll -``` - -Properties: - -```javascript -number detail -DOMAbstractView view -``` - -* * * - -### Wheel Events {#wheel-events} - -Event names: - -``` -onWheel -``` - -Properties: - -```javascript -number deltaMode -number deltaX -number deltaY -number deltaZ -``` - -* * * - -### Media Events {#media-events} - -Event names: - -``` -onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted -onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay -onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend -onTimeUpdate onVolumeChange onWaiting -``` - -* * * - -### Image Events {#image-events} - -Event names: - -``` -onLoad onError -``` - -* * * - -### Animation Events {#animation-events} - -Event names: - -``` -onAnimationStart onAnimationEnd onAnimationIteration -``` - -Properties: - -```javascript -string animationName -string pseudoElement -float elapsedTime -``` - -* * * - -### Transition Events {#transition-events} - -Event names: - -``` -onTransitionEnd -``` - -Properties: - -```javascript -string propertyName -string pseudoElement -float elapsedTime -``` - -* * * - -### Other Events {#other-events} - -Event names: - -``` -onToggle -```