You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/learn/thinking-in-react.md
+50-47Lines changed: 50 additions & 47 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
---
2
2
title: تفکر به سبک ریاکت
3
3
---
4
-
<Introdir="rtl">
4
+
<Intro>
5
5
کتابخانهی ریاکت میتواند نگاه شما به طراحیهایی که می بینید و برنامههایی که میسازید را٬ تغییر دهد.وقتی یک رابط کاربری را با ریاکت میسازید، ابتدا آن را به قسمتهایی به نام کامپوننتها تقسیم میکنید.
6
6
سپس، وضعیتهای بصری مختلف را برای هر یک از کامپوننتهایتان توصیف میکنید. در نهایت، کامپوننتهای خود را به گونهای با یکدیگر ارتباط میدهید که داده از طریق آنها جابهجا شود. در اینجا ما مراحل ساخت یک جدول با قابلیت سرچ اطلاعات را با شما برای هدف اموزش به اشتراک میگذاریم
7
7
</Intro>
8
8
## Start with the mockup {/*start-with-the-mockup*/}
9
-
<pdir="rtl">
9
+
10
10
تصور کنید شما همین الان دیتایی از طریق ای پی آی و فایل ماکآپ را از دیزاینر دارید. فایل دیتا٬ اطلاعاتی مثل فایل زیر را شامل میشود:
برای پیاده سازی هر دیزاینی ما این پنج قدم را برمی داریم:
43
43
44
44
## Step 1: Break the UI into a component hierarchy {/*step-1-break-the-ui-into-a-component-hierarchy*/}
45
-
<pdir="rtl">
45
+
46
46
اول دور هر کامپوننت و زیر کامپوننت در دیزاین خط بکشید و برای آنها اسم بگذارید. اگر با یک طراح همکاری میکنید، ممکن است او این کامپوننتها را در ابزار طراحی خود قبلاً نامگذاری کرده باشد. از او بپرسید!
47
47
بسته به بکگراند شما، میتوانید به روشهای مختلف دربارهی تقسیم یک طراحی به کامپوننتها فکر کنید.
48
-
</p>
48
+
49
49
-**برنامهنویسی**--از تکنیکهای مشابه برای تصمیمگیری در مورد اینکه آیا باید یک تابع یا شیء جدید ایجاد کنید استفاده کنید
50
50
یکی از این تکنیکها اصل single responsibility است، به این معنی که یک کامپوننت بهتر است تنها یک کار را انجام دهد. اگر کامپوننت به طور مداوم بزرگتر شود، باید به زیرکامپوننتهای کوچکتر تجزیه شود.
-**CSS**--بررسی کنید که برای چه عناصری از کلاسها استفاده خواهید کرد. (با این حال، کامپوننتها کمتر جزئیات ریز دارند.)
54
54
55
-
-**design**--
56
-
در نظر بگیرید که چگونه لایههای طراحی را سازماندهی خواهید کرد
55
+
-**design**--در نظر بگیرید که چگونه لایههای طراحی را سازماندهی خواهید کرد
57
56
اگر فایل جیسون شما ساختار مناسبی داشته باشد، اغلب متوجه می شوید که به طور طبیعی با ساختار کامپوننتهای رابط کاربری شما همخوانی دارد. این به این دلیل است که مدلهای رابط کاربری و داده اغلب همان معماری اطلاعاتی را دارند - به اصطلاح، همان شکل. رابط کاربری خود را به
58
57
کامپوننتها تقسیم کنید، به گونهای که هر کامپوننت با یک قسمت از مدل داده شما مطابقت داشته باشد
اگر به کامپوننت ۳(جدول محصولات) نگاه کنید، میبینید که هدر جدول (شامل برچسبهای "نام" و "قیمت") قسمت جداگانهای نیست. این مسئله از سلیقهای است و میتوانید هر دو را انتخاب کنید. در این مثال، این بخش جزء کامپوننت ۳است زیرا داخل لیست کامپوننت ۳ ظاهر میشود. با این حال، اگر این هدر به طور پیچیدهتری رشد کند (مثلاً اگر مرتبسازی را اضافه کنید)، میتوانید آن را به عنوان یک کامپوننت جداگانه با نام(هدر جدول محصولات) جابجا کنید.
82
+
83
+
84
+
اگر به کامپوننت ۳(جدول محصولات) نگاه کنید، میبینید که هدر جدول (شامل برچسبهای "نام" و "قیمت") قسمت جداگانهای نیست. این مسئله سلیقهای است و میتوانید هر دو را انتخاب کنید. در این مثال، این بخش جزء کامپوننت ۳است زیرا داخل لیست کامپوننت ۳ ظاهر میشود. با این حال، اگر این هدر به طور پیچیدهتری رشد کند (مثلاً اگر مرتبسازی را اضافه کنید)، میتوانید آن را به عنوان یک کامپوننت جداگانه با نام(هدر جدول محصولات) جابجا کنید.
85
+
85
86
86
87
هماکنون که اجزای ماکاپ را شناسایی کردهاید، آنها را به صورت سلسلهمراتبی قرار دهید. کامپوننتی که در داخل یک کامپوننت دیگر در نمونه طراحی ظاهر میشوند، باید به عنوان زیرمجموعه در سلسلهمراتب ظاهر شوند.
87
-
</p>
88
+
88
89
89
90
-`FilterableProductTable`
90
91
-`SearchBar`
@@ -100,7 +101,7 @@ title: تفکر به سبک ریاکت
100
101
101
102
[state](/learn/state-a-components-memory) لینک به
102
103
103
-
</p>
104
+
</p>
104
105
105
106
<Sandpack>
106
107
@@ -216,76 +217,77 @@ td {
216
217
<pdir="rtl">
217
218
بعد ساختن کامپوننتهای خود، شما یک کتابخانه از کامپوننتهای قابل استفاده مجدد خواهید داشت که مدل دادههای شما را نمایش میدهند. به دلیل اینکه این برنامه از نوع استاتیک است، کامپوننتها فقط JSX را بازمیگردانند. کامپوننت، در بالای سلسلهمراتب (FilterableProductTable) مدل دادههای شما را به عنوان یک ویژگی دریافت میکند. این با نام "جریان داده یکطرفه" شناخته میشود زیرا دادهها از کامپوننته بالاتر در سلسلهمراتب به کامپوننتهای پایینتر در درخت جریان مییابند
218
219
</p>
219
-
<Pitfalldir="rtl">
220
+
<Pitfall>
220
221
در این نقطه، شما نباید از هیچ مقدار وضعیتی استفاده کنید. این مرحله برای مرحله بعدی است!
221
222
</Pitfall>
222
223
223
224
## Step 3: Find the minimal but complete representation of UI state {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/}
224
-
<pdir="rtl">
225
+
225
226
برای ایجاد تعامل در رابط کاربری، باید به کاربران امکان تغییر مدل دادههای زیرین خود را بدهید. برای این کار از وضعیت (state) استفاده خواهید کرد.
226
-
</p>
227
+
227
228
<pdir="rtl">
228
229
وضعیت را به عنوان مجموعه حداقلی از دادههای تغییر پذیری تصور کنید که برنامه شما نیاز دارد که به خاطر بسپارد. مهمترین اصل در ساختاردهی وضعیت، حفظ اصل DRY (Don't Repeat Yourself) است. [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) کمترین حالتی که نیازهای برنامهی شما از state دارد را تعیین کنید و سایر موارد را به صورت درخواستی محاسبه کنید. به عنوان مثال، اگر در حال ساختن یک لیست خرید هستید، میتوانید موارد را به صورت یک آرایه در state ذخیره کنید. اگر میخواهید تعداد موارد در لیست را نشان دهید، تعداد موارد را به عنوان یک مقدار وضعیت جدید درنظر نگیرید - در عوض، طول آرایهتان را بخوانید.
229
230
</p>
230
-
<pdir="rtl"> حالا به تمام قسمت های دیتا در این اپلیکیشن نگاه کنید:</p>
231
+
حالا به تمام قسمت های دیتا در این اپلیکیشن نگاه کنید:
232
+
231
233
1-FilterableProductTable
232
234
2-SearchBar
233
235
3-ProductTable
234
236
4-ProductCategoryRow
235
237
5-ProductRow
236
-
<pdir="rtl">
238
+
237
239
کدام یکی از اینها state هستند؟
238
240
اول آنهایی که نیستند را مشخص میکنیم:
239
-
</p>
240
-
<lidir="rtl">
241
+
242
+
<li>
241
243
ایا در طول زمان **بدون تغییر** خواهد ماند؟ اگر بله پس استیت نیست-
242
244
آیا **از یک کامپوننت والد** با پراپس پاس داده شده؟ اگر بله پس استیت نیست-
243
245
ایا میتوانید آن را خودتان به دست بیاورید؟ **براساس استیت فعلی یا پراپس کامپوننت** اگر بله پس قطعا استیت نیست!-
244
246
</li>
245
247
246
-
<pdir="rtl">
248
+
247
249
هرچه به جز این حالت ها باشد٬ استیت است
248
250
state
249
-
</p>
250
-
<pdir="rtl"> یکبار دیگر باهم مرور کنیم:</p>
251
-
<pdir="rtl">
251
+
252
+
یکبار دیگر باهم مرور کنیم:
253
+
252
254
آیا **از یک کامپوننت والد** با پراپس پاس داده شده؟ اگر بله پس استیت نیست-
253
255
ایا میتوانید آن را خودتان به دست بیاورید؟ **براساس استیت فعلی یا پراپس کامپوننت** اگر بله پس قطعا استیت نیست!-
254
-
</p>
255
-
<oldir="rtl">
256
+
257
+
<ol>
256
258
<li>اگر اصل لیست محصولات به عنوان پراپس پاس داده شده٬ پس استیت یا وضعیت نیست</li>
257
259
<li>متن جستجو به نظر استیت است چرا که به مرور زمان تغییر میکند و ما نمیتوانیم آن را محاسبه کنیم</li>
258
260
<li>مقدار چک باکس یک استیت است زیرا محاسبه نمیشود و به مرور زمان تغییر میکند</li>
259
261
<li>لیست محصولات فیلتر شده استیت نیست٬ زیرا میتوانیم آن را حساب کنیم! تنها به لیست اولیه و مقداری که کاربر جستجو کرده به همراه مقدار تکس باکس نیاز داریم </li>
260
262
</ol>
261
-
<p>
262
-
یعنی ما فقط متن جستجو شده و مقدار تکست باکس را به عنوان استیت نگه میداریم :)
263
-
</p>
263
+
264
+
یعنی ما فقط متن جستجو شده و مقدار تکست باکس را به عنوان استیت نگه میداریم
265
+
264
266
<DeepDive>
265
267
266
268
### Props vs State {/*props-vs-state*/}
267
-
<divdir="rtl">
268
-
<pdir="rtl">
269
+
270
+
269
271
دو نوع مدل دیتا در ری اکت داریم: وضعیت (state) و (props).
270
272
این دو باهم تفاوت زیادی دارند:
271
-
</p>
273
+
272
274
273
275
[**پراپس** شبیه ارگیومنت هایی که به تایع پاس میدهید](/learn/passing-props-to-a-component) . آنها به کامپوننت والد اجازه می دهند که دیتا را به فرزند خود پاس دهد و ظاهر آن را دستکاری کند. مثلا: یک `form` میتواند رنگ
274
276
را به عنوان پراپس به کامپوننت `Button` پاس دهد.
275
277
-[**استیت** مثل حافظه ی یک کامپوننت است](/learn/state-a-components-memory) به کامپوننت این امکان را میدهد تا تغییرات اطلاعات را ثبت کند و به آنها پاسخ مناسب دهد. مثلا کامپوننت دکمه میتواند تغییراتی مثل رفتن موس روی خود را در استیت ثبت کند
276
-
</div>
278
+
277
279
278
280
</DeepDive>
279
-
<pdir="rtl">
281
+
280
282
پراپها (Props) و استیتها (State) متفاوت هستند، اما با هم کار میکنند. یک کامپوننت والد (Parent) اغلب برخی اطلاعات را در استیت نگه میدارد (تا بتواند آنها را تغییر دهد) و به عنوان پراپ به کامپوننتهای فرزند (Child) ارسال میکند. اگر هنوز تفاوت بین آنها برای اولین بار کاملاً روشن نشده باشد، مشکلی ندارد. برای کامل شدن درک این موضوع، نیاز به تمرین کمی دارد!
281
-
</p>
282
-
</DeepDive>
283
+
284
+
283
285
284
286
## Step 4: Identify where your state should live {/* step-4-identify-where-your-state-should-live */}
285
-
<pdir="rtl">
287
+
286
288
بعد از شناسایی دادههای حداقلی مرتبط با برنامهی شما، نیاز دارید تعیین کنید که کدام کامپوننت مسئول تغییر این دادههاست، یا به عبارتی، مالک (owns) این دادهها است. به یاد داشته باشید: ریاکت از جریان دادهی یک طرفه استفاده میکند و دادهها را از کامپوننت والد به کامپوننتهای فرزند در سلسلهمراتب ارسال میکند. ممکن است اولیهاش که کدام کامپوننت باید مالک دادههایی باشد که در اختیار دارد، به وضوح نباشد. اگر تازه با این مفهوم آشنا شدهاید، ممکن است چالش برانگیز باشد، اما با دنبال کردن این
287
-
</p>
288
-
<pdir="rtl">
289
+
290
+
289
291
برای هر قطعه از استیت (state) در برنامهی شما:
290
292
291
293
*تمام* کامپوننتهایی که بر اساس آن استیت چیزی را رندر میکنند را شناسایی کنید.
@@ -295,21 +297,20 @@ state
295
297
همچنین میتوانید استیت را در یکی از کامپوننتهای بالاتر از کامپوننت مشترک آنها قرار دهید.
296
298
اگر نمیتوانید کامپوننتی پیدا کنید که استیت را به صورت منطقی مدیریت کند، میتوانید یک کامپوننت جدید را که تنها برای نگهداری استیت ایجاد شده باشد بسازید و آن را در جایی در سلسلهمراتب بالاتر از کامپوننت مشترک قرار دهید.
297
299
در مرحلهی قبلی، دو قطعه از استیت را در این برنامه پیدا کردید: متن ورودی جستجو و مقدار چکباکس. در این مثال، همیشه همراه یکدیگر ظاهر میشوند، بنابراین منطقی است که آنها را در یک جایگاه قرار دهید
298
-
</p>
300
+
299
301
300
302
حالا بیایید از راهبرد ما مسئله را بررسی کنیم
301
-
<pdir="rtl">
303
+
302
304
شناسایی کامپوننتهایی که از استیت استفاده میکنند: ***
303
305
304
306
ProductTable نیاز دارد که لیست محصولات را بر اساس این استیت (متن جستجو و مقدار چکباکس) فیلتر کند. ***
305
307
SearchBar نیاز دارد که این استیت (متن جستجو و مقدار چکباکس) را نمایش دهد. ***
306
308
یافتن پدر مشترک آنها: اولین کامپوننت والد که هر دو کامپوننت با هم به اشتراک میگذارند، FilterableProductTable است. ***
307
309
تصمیم برای محل قرارگیری استیت: ما مقادیر متن فیلتر و وضعیت چکباکس را در FilterableProductTable نگهداری خواهیم کرد. ***
308
310
بنابراین مقادیر استیت در FilterableProductTable قرار خواهند گرفت.
309
-
</p>
310
-
<pdir="rtl">
311
+
311
312
استیت را درون کامپوننتی که [`useState()` Hook.](/reference/react/useState) دارد اضافه کنید. Hookها توابه خاصی هستند که به شما اجازه میدهند تا قدرت ریاکت را درونشان قلاب کنید. دو متغییر استیت در بالای `FilterableProductTable`تعریف و مقدار پیشفرض آنها را مشخص کنید:
312
-
</p>
313
+
313
314
314
315
```js
315
316
functionFilterableProductTable({ products }) {
@@ -460,7 +461,9 @@ td {
460
461
461
462
</Sandpack>
462
463
463
-
<p dir="rtl"> توجه کنید که هنوز ویرایش فرم کار نمیکند. یک خطا در کنسول محیط آزمایشی بالا وجود دارد که دلیل آن را توضیح میدهد.</p>
464
+
465
+
توجه کنید که هنوز ویرایش فرم کار نمیکند. یک خطا در کنسول محیط آزمایشی بالا وجود دارد که دلیل آن را توضیح میدهد.
466
+
464
467
<ConsoleBlock level="error">
465
468
466
469
You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field.
0 commit comments