diff --git a/content/docs/context.md b/content/docs/context.md index c6882fe08..6e81b704e 100644 --- a/content/docs/context.md +++ b/content/docs/context.md @@ -4,58 +4,58 @@ title: Context permalink: docs/context.html --- -Context provides a way to pass data through the component tree without having to pass props down manually at every level. +Context راهی را برای انتقال داده در درخت کامپوننت بدون نیاز به انتقال دستیه props به تمام سطح های پایینی فراهم می‌کند. -In a typical React application, data is passed top-down (parent to child) via props, but this can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree. +در یک اپلیکیشن معمولی ری‌اکت, داده از طریق props از بالا به پایین (والدین به فرزند) منتقل می‌شود, اما این کار برای انواع خاصی از props ها (برای مثال: locale preference, تم رابط کاربری) که مورد نیاز بسیاری از کامپوننت ها در یک اپلیکیشن است می‌تواند سنگین باشد. Context راهی را برای به اشتراک گذاری مقادیری مانند این بین کامپوننت‌ها بدون نیاز به انتقال prop صریحا‍ً‌ از هر سطح درخت فراهم می‌کند. -- [When to Use Context](#when-to-use-context) -- [Before You Use Context](#before-you-use-context) +- [چه موقع باید از Context استفاده کرد](#when-to-use-context) +- [قبل از اینکه از Context استفاده کنید](#before-you-use-context) - [API](#api) - [React.createContext](#reactcreatecontext) - [Context.Provider](#contextprovider) - [Class.contextType](#classcontexttype) - [Context.Consumer](#contextconsumer) - [Context.displayName](#contextdisplayname) -- [Examples](#examples) - - [Dynamic Context](#dynamic-context) - - [Updating Context from a Nested Component](#updating-context-from-a-nested-component) - - [Consuming Multiple Contexts](#consuming-multiple-contexts) -- [Caveats](#caveats) -- [Legacy API](#legacy-api) +- [مثال ها](#examples) + - [Context پویا](#dynamic-context) + - [به‌روز‌رسانی Context از یک کامپوننت تودرتو](#updating-context-from-a-nested-component) + - [مصرف چندین Context](#consuming-multiple-contexts) +- [هشدارها](#caveats) +- [API موروثی](#legacy-api) -## When to Use Context {#when-to-use-context} +## چه موقع باید از Context استفاده کرد {#when-to-use-context} -Context is designed to share data that can be considered "global" for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a "theme" prop in order to style the Button component: +Context برای به اشتراک گذاری داده ای طراحی شده است که می‌تواند برای درختی از ری‌اکت کامپوننت ها عمومی تلقی شود٬ مانند کاربر تایید شده‌ی فعلی٬ زمینه٬ یا زبان ترجیحی. برای مثال٬ ما در کد زیر یک prop به نام "theme" را به صورت دستی برای style دادن به کامپوننت Button انتقال می‌دهیم: `embed:context/motivation-problem.js` -Using context, we can avoid passing props through intermediate elements: +با استفاده از context, می‌توانیم از انتقال props از بین المنت‌های میانی دوری کنیم: `embed:context/motivation-solution.js` -## Before You Use Context {#before-you-use-context} +## قبل از اینکه از Context استفاده کنید {#before-you-use-context} -Context is primarily used when some data needs to be accessible by *many* components at different nesting levels. Apply it sparingly because it makes component reuse more difficult. + در درجه اول Context زمانی استفاده می‌شود که برخی از داده‌ها باید توسط *بسیاری* از کامپوننت‌ها در سطح‌های مختلف تودرتویی در دسترس قرار بگیرند. از آنجایی که استفاده مجدد کامپوننت را سخت‌تر می‌کند٬ از آن کم استفاده کنید. -**If you only want to avoid passing some props through many levels, [component composition](/docs/composition-vs-inheritance.html) is often a simpler solution than context.** +**اگر فقط می‌خواهید که از انتقال برخی از داده‌ها بین بسیاری از سطح‌ها اجتناب کنید, اغلب [composition کامپوننت](/docs/composition-vs-inheritance.html) راه‌حلی ساده‌تر از context می‌باشد.** -For example, consider a `Page` component that passes a `user` and `avatarSize` prop several levels down so that deeply nested `Link` and `Avatar` components can read it: +برای مثال٬ یک کامپوننت به نام `Page` را در نظر بگیرید که یک prop به نام `user` و `avatarSize` را چندین سطح به پایین منتقل می‌کند به طوری که کامپوننت‌های عمیقا تودرتو شده‌ی `Link` و `Avatar` بتوانند آن را بخوانند: ```js -// ... which renders ... +// ... که رندر می‌کند ... -// ... which renders ... +// ... که رندر می‌کند ... -// ... which renders ... +// ... که رندر می‌کند ... ``` -It might feel redundant to pass down the `user` and `avatarSize` props through many levels if in the end only the `Avatar` component really needs it. It's also annoying that whenever the `Avatar` component needs more props from the top, you have to add them at all the intermediate levels too. +انتقال propهای `user` و `avatarSize` به پایین از بین بسیاری از سطح‌ها ممکن است زائد به نظر بیاید اگر در نهایت فقط کامپوننت `Avatar` است که به آن نیاز دارد. این نیز آزاردهنده است که هر زمانی که کامپوننت `Avatar` به تعداد بیشتری props از بالا احتیاج داشته باشد٬ شما باید آن‌ها را در تمامی سطح‌های میانی هم اضافه کنید. -One way to solve this issue **without context** is to [pass down the `Avatar` component itself](/docs/composition-vs-inheritance.html#containment) so that the intermediate components don't need to know about the `user` or `avatarSize` props: +یک راه حل برای این مسئله **بدون context** این است که [خود کامپوننت `Avatar` را به پایین انتقال دهیم](/docs/composition-vs-inheritance.html#containment) به طوری که کامپوننت‌های میانی نیازی به دانستن درمورد propهای `user` یا `avatar` نداشته باشند: ```js function Page(props) { @@ -68,21 +68,23 @@ function Page(props) { return ; } -// Now, we have: +// اکنون, داریم: -// ... which renders ... +// ... که رندر می‌کند ... -// ... which renders ... +// ... که رندر می‌کند ... -// ... which renders ... +// ... که رندر می‌کند ... {props.userLink} ``` -With this change, only the top-most Page component needs to know about the `Link` and `Avatar` components' use of `user` and `avatarSize`. +با این تغییر٬ فقط بالاترین کامپوننت یعنی Page باید در مورد استفاده `user` و ‍`avatarsize` توسط کامپوننت‌های `Link` و `Avatar` بداند. -This *inversion of control* can make your code cleaner in many cases by reducing the amount of props you need to pass through your application and giving more control to the root components. However, this isn't the right choice in every case: moving more complexity higher in the tree makes those higher-level components more complicated and forces the lower-level components to be more flexible than you may want. +این *وارونگی کنترل* در بسیاری از موارد می‌تواند کد شما را از طریق کاهش تعداد propهایی که باید در اپلیکیشن خود انتقال دهید تمیزتر کند و کنترل بیشتری به کامپوننت‌های پایه می‌دهد. +با این حال٬ این کار در هر موردی تصمیم درست نیست: انتقال پیچیدگی بیشتر به بالا در درخت باعث پیچیده‌تر شدن کامپوننت‌های سطح-بالا می‌شود و ممکن است کامپوننت‌های سطح-پایین را مجبور به انعطاف‌پذیری بیشتر از آنچه که می‌خواهید کند. -You're not limited to a single child for a component. You may pass multiple children, or even have multiple separate "slots" for children, [as documented here](/docs/composition-vs-inheritance.html#containment): +شما برای یک کامپوننت محدود به یک فرزند نیستید. شما می‌توانید چندین فرزند٬ یا حتی چندین "slots" جداگانه برای فرزندان٬ [همانطور که در اینجا مستند شده است +](/docs/composition-vs-inheritance.html#containment)انتقال دهید: ```js function Page(props) { @@ -104,9 +106,9 @@ function Page(props) { } ``` -This pattern is sufficient for many cases when you need to decouple a child from its immediate parents. You can take it even further with [render props](/docs/render-props.html) if the child needs to communicate with the parent before rendering. +این الگو در بسیاری از مواردی که باید یک فرزند را از والدین نزدیک آن جدا کرد کافی است. در صورتی که فرزند قبل از رندر شدن نیاز به برقراری ارتباط با والدین را داشته باشد٬ شما می‌توانید این قضیه را با [render-props](/docs/render-props.html) ادامه دهید. -However, sometimes the same data needs to be accessible by many components in the tree, and at different nesting levels. Context lets you "broadcast" such data, and changes to it, to all components below. Common examples where using context might be simpler than the alternatives include managing the current locale, theme, or a data cache. +با این حال٬ گاهی‌اوقات یک داده‌ی یکسان باید توسط کامپوننت‌های زیادی در درخت٬ و سطح‌های تودرتوی مختلفی در دسترس قرار گیرد. Context اجازه پخش کردن همچین داده‌ای٬ و اجازه تغییر آن به تمام کامپوننت‌های زیرین را به شما می‌دهد. مثال‌های رایجی که استفاده از context در آن‌ها ممکن است آسان‌تر از راه‌های جایگزین آن باشد شامل مدیریت locale فعلی٬ زمینه, یا داده حافظه نهان می‌باشد. ## API {#api} @@ -116,27 +118,27 @@ However, sometimes the same data needs to be accessible by many components in th const MyContext = React.createContext(defaultValue); ``` -Creates a Context object. When React renders a component that subscribes to this Context object it will read the current context value from the closest matching `Provider` above it in the tree. +کد بالا یک شیٔ context ایجاد می‌کند. وقتی ری‌اکت یک کامپوننتی را رندر می‌کند که به این شیء context ارجاع می‌کند (subscribes)٬ مقدار context حاضر را از نزدیکترین `Provider` مرتبط بالایی در درخت خواهد خواند. -The `defaultValue` argument is **only** used when a component does not have a matching Provider above it in the tree. This can be helpful for testing components in isolation without wrapping them. Note: passing `undefined` as a Provider value does not cause consuming components to use `defaultValue`. +آرگومان `defaultValue` **فقط** زمانی استفاده می‌شود که یک کامپوننت در بالاتر از خود در درخت یک Provider مطابق نداشته باشد. این مورد می‌تواند برای تست کردن کامپوننت‌ها در انزوا بدون wrap کردن آن‌ها مفید باشد. توجه داشته باشید: انتقال `undefined` به عنوان مقدار Provider باعث نمی‌شود که کامپوننت‌هایی که از آن استفاده می‌کنند از `defaultValue` استفاده کنند. ### `Context.Provider` {#contextprovider} ```js - + ``` -Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes. +هر شئ context ای با یک کامپوننت ری‌اکتی Provider همراه می‌شود که به کامپوننت‌های مصرف‌کننده آن این اجازه را می‌دهد که تغییرات context را به اشتراک بگذارند. -Accepts a `value` prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers. Providers can be nested to override values deeper within the tree. +این کامپوننت یک prop به نام `value` را می‌پذیرد که به کامپوننت‌های مصرف‌کننده آن که نوادگان این Provider می‌باشند٬ انتقال یابد. Provider می‌تواند به چندین مصرف‌کننده متصل شود. Providerها می‌توانند به شکلی تودرتو شوند تا valueهایی را که در عمق درخت وجود دارند باطل کنند.. -All consumers that are descendants of a Provider will re-render whenever the Provider's `value` prop changes. The propagation from Provider to its descendant consumers (including [`.contextType`](#classcontexttype) and [`useContext`](/docs/hooks-reference.html#usecontext)) is not subject to the `shouldComponentUpdate` method, so the consumer is updated even when an ancestor component skips an update. +هرزمانی که prop ‍‍‍‍`value` مربوط به Provider تغییر کند تمام مصرف‌کننده‌هایی که نوادگان یک Provider هستند دوباره رندر می‌شوند. Propagation از Provider تا نوادگان مصرف‌کننده آن (شامل [`.contextType`](#classcontexttype) و [`useContext`](/docs/hooks-reference.html#usecontext)) مشمول متد `shouldComponentUpdate` نیستند٬ بنابراین حتی زمانی که جد کامپوننت یک به‌ روز‌رسانی را رد می‌کند٬ مصرف‌کننده آن به روزرسانی می‌شود. -Changes are determined by comparing the new and old values using the same algorithm as [`Object.is`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description). +تغییرات بوسیله مقایسه value های جدید و قدیم با استفاده از همان الگوریتم [`Object.is`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description) مشخص می‌شوند. -> Note +> یادداشت > -> The way changes are determined can cause some issues when passing objects as `value`: see [Caveats](#caveats). +>نحوه تعیین تغییرات هنگام انتقال اشیاء به عنوان `value` می‌تواند مشکل‌ساز شود: [هشدارها](#caveats) را ببینید. ### `Class.contextType` {#classcontexttype} @@ -144,7 +146,7 @@ Changes are determined by comparing the new and old values using the same algori class MyClass extends React.Component { componentDidMount() { let value = this.context; - /* perform a side-effect at mount using the value of MyContext */ + /* با استفاده از مقدار MyContext یک اثرجانبی هنگام mount ایجاد کنید */ } componentDidUpdate() { let value = this.context; @@ -156,19 +158,19 @@ class MyClass extends React.Component { } render() { let value = this.context; - /* render something based on the value of MyContext */ + /* چیزی را بر اساس مقدار MyContext رندر کنید */ } } MyClass.contextType = MyContext; ``` -The `contextType` property on a class can be assigned a Context object created by [`React.createContext()`](#reactcreatecontext). This lets you consume the nearest current value of that Context type using `this.context`. You can reference this in any of the lifecycle methods including the render function. +یک شیئ Context که با [`React.createContext()`](#reactcreatecontext) ایجاد شده است می‌تواند به ویژگی `contextType` در یک کلاس اختصاص یابد. این کار به شما اجازه می‌دهد که از نزدیک‌ترین مقدار فعلی `contextType` با استفاده از `this.context` استفاده کنید. شما می‌توانید از این قضیه در تمام متدهای چرخه‌حیات از جمله تابع رندر استفاده کنید. -> Note: +> یادداشت: > -> You can only subscribe to a single context using this API. If you need to read more than one see [Consuming Multiple Contexts](#consuming-multiple-contexts). +> شما با استفاده از این API فقط می توانید در یک context واحد مشترک شوید. در صورت نیاز به خواندن بیش از یک مورد ، به [مصرف چندین Context](#consuming-multiple-contexts) مراجعه کنید . > -> If you are using the experimental [public class fields syntax](https://babeljs.io/docs/plugins/transform-class-properties/), you can use a **static** class field to initialize your `contextType`. +> اگر از [syntax تجربی فیلدهای کلاس عمومی](https://babeljs.io/docs/plugins/transform-class-properties/) استفاده می کنید٬ می توانید از یک فیلد کلاس **استاتیک** برای مقداردهی اولیه `contextType` خود استفاده کنید. ```js @@ -176,7 +178,7 @@ class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; - /* render something based on the value */ + /* چیزی را بر اساس مقدار آن رندر کنید */ } } ``` @@ -185,37 +187,37 @@ class MyClass extends React.Component { ```js - {value => /* render something based on the context value */} + {value => /* چیزی را بر اساس مقدار context رندر کنید */} ``` -A React component that subscribes to context changes. This lets you subscribe to a context within a [function component](/docs/components-and-props.html#function-and-class-components). +یک کامپوننت ری‌اکت که تغییرات context را به اشتراک می‌گذارد. این کار به شما اجازه می‌دهد که یک context را داخل [کامپوننت تابع](/docs/components-and-props.html#function-and-class-components) به اشتراک بگذارید. -Requires a [function as a child](/docs/render-props.html#using-props-other-than-render). The function receives the current context value and returns a React node. The `value` argument passed to the function will be equal to the `value` prop of the closest Provider for this context above in the tree. If there is no Provider for this context above, the `value` argument will be equal to the `defaultValue` that was passed to `createContext()`. +نیاز به یک [کامپوننت به عنوان فرزند](/docs/render-props.html#using-props-other-than-render) دارد. این تابع مقدار context فعلی را دریافت می‌کند و یک نود ری‌اکت برمی‌گرداند. آرگومان `value` ای که به تابع داده شده است با prop `value` نزدیک‌ترین Provider بالاتر از آن در درخت برای این context برابر خواهد بود. اگر در بالاتر هیچ Provider ای برای این context وجود نداشت٬ آرگومان `value` با `defaultValue` ای که به `createContext()` داده شد٬ برابر خواهد بود. -> Note +> یادداشت > -> For more information about the 'function as a child' pattern, see [render props](/docs/render-props.html). +> برای اطلاعات بیشتر در مورد الگوی 'تابع به عنوان فرزند'٬ [render props](/docs/render-props.html) را ببینید. ### `Context.displayName` {#contextdisplayname} -Context object accepts a `displayName` string property. React DevTools uses this string to determine what to display for the context. +شیئ context یک ویژگی از نوع رشته با نام `displayName` می‌پذیرد. DevTools ری‌اکت از این رشته استفاده می‌کند تا مشخص کند که چه چیزی را برای عنوان context نمایش دهد. -For example, the following component will appear as MyDisplayName in the DevTools: +به عنوان مثال٬ کامپوننت زیر در DevTools به صورت MyDisplayName ظاهر می‌شود: ```js{2} -const MyContext = React.createContext(/* some value */); +const MyContext = React.createContext(/* یک مقداری */); MyContext.displayName = 'MyDisplayName'; // "MyDisplayName.Provider" in DevTools // "MyDisplayName.Consumer" in DevTools ``` -## Examples {#examples} +## مثال ها {#examples} -### Dynamic Context {#dynamic-context} +### Context پویا {#dynamic-context} -A more complex example with dynamic values for the theme: +یک مثال پیچیده‌تر با مقادیر پویا برای theme: **theme-context.js** `embed:context/theme-detailed-theme-context.js` @@ -226,9 +228,9 @@ A more complex example with dynamic values for the theme: **app.js** `embed:context/theme-detailed-app.js` -### Updating Context from a Nested Component {#updating-context-from-a-nested-component} +### به‌روز‌رسانی Context از یک کامپوننت تودرتو {#updating-context-from-a-nested-component} -It is often necessary to update the context from a component that is nested somewhere deeply in the component tree. In this case you can pass a function down through the context to allow consumers to update the context: +اغلب به روزرسانی context از کامپوننت‌ای که در جایی عمیق در درخت واقع شده لازم است. در این مورد شما می‌توانید یک تابع را از طریق context به پایین منتقل کنید تا به مصرف‌کنندگان آن اجازه به روزرسانی context را بدهید: **theme-context.js** `embed:context/updating-nested-context-context.js` @@ -239,28 +241,27 @@ It is often necessary to update the context from a component that is nested some **app.js** `embed:context/updating-nested-context-app.js` -### Consuming Multiple Contexts {#consuming-multiple-contexts} +### مصرف چندین context {#consuming-multiple-contexts} -To keep context re-rendering fast, React needs to make each context consumer a separate node in the tree. +برای این‌که رندرشدن های مجدد را سریع نگه داریم٬ ری‌اکت باید هر مصرف‌کننده context را به یک نود جداگانه در درخت تبدیل کند. `embed:context/multiple-contexts.js` -If two or more context values are often used together, you might want to consider creating your own render prop component that provides both. +اگر دو یا چند مقدار از context زیاد با هم استفاده شدند، بهتر است در نظر داشته باشید که کامپوننت render propای خودتان ایجاد کنید که شامل هر دوی آنها شود. -## Caveats {#caveats} +## هشدارها {#caveats} -Because context uses reference identity to determine when to re-render, there are some gotchas that could trigger unintentional renders in consumers when a provider's parent re-renders. For example, the code below will re-render all consumers every time the Provider re-renders because a new object is always created for `value`: +به دلیل این‌که context از هویت مرجع برای مشخص کردن این‌که چه زمانی باید رندر دوباره صورت بگیرد استفاده می‌کند٬ به دلیل برخی خطاها ممکن است هنگامی که والدین Provider دوباره رندر می‌شوند٬ در مصرف‌کنندگان آن موجب رندر ناخواسته شود. برای مثال٬ هر زمانی که Provider دوباره به خاطر ایجاد یک شیئ جدید که همیشه برای `value` ایجاد می‌شود٬ رندر می‌شود کد زیر تمام مصرف‌کنندگان را دوباره رندر می‌کند: `embed:context/reference-caveats-problem.js` -To get around this, lift the value into the parent's state: +برای پی بردن به این موضوع٬ مقدار را به state والدین ببرید: `embed:context/reference-caveats-solution.js` -## Legacy API {#legacy-api} +## API موروثی {#legacy-api} -> Note +> یادداشت > -> React previously shipped with an experimental context API. The old API will be supported in all 16.x releases, but applications using it should migrate to the new version. The legacy API will be removed in a future major React version. Read the [legacy context docs here](/docs/legacy-context.html). - +> ری‌اکت قبلا با یک API context آزمایشی منتشر شد. API قدیمی در تمام نسخه های ۱۶.x پشتیبانی خواهد شد٬ اما اپلیکیشن‌هایی که از آن استفاده می‌کنند باید به نسخه جدید ارتقاء دهند. API موروثی در نسخه اصلی React در آینده حذف می شود. [اسناد context موروثی را اینجا](/docs/legacy-context.html) بخوانید.