به نام خدا
مجموعه سوال و جواب‌های ری‌اکت React.js
جعفررضایی

اگه از کتاب خوشتون اومد به گیت‌هابمون مراجعه کنین و بهمون⭐️ بدین. اگر هم قصد مشارکت داشتید خیلی خوشحال می‌شیم 😃 http://github.com/mariotek

دانلود کتاب به فرمت‌های PDF/Epub

می‌تونین خیلی راحت از نسخه آنلاین استفاده کنین یا اگه به فایل‌ کتاب می‌خوایین دسترسی داشته باشین، از بخش ریلیزهای گیت هاب(این لینک) به فرمت‌های مختلف دانلود کنین.

فهرست

ردیف سوال
هسته ری‌اکت
1 ری‌اکت چیه؟
2 اصلی‌ترین ویژگی‌های ری‌اکت کدوما هستن؟
3 JSX چیه؟
4 تفاوت‌های Element و Component چیه؟
5 تو ری‌اکت چطوری کامپوننت می‌سازیم؟
6 چه موقع‌هایی باید از Class Component بجای Function Component استفاده کنیم؟
7 Pure Components چیه؟
8 state تو ری‌اکت چیکار می‌کنه؟
9 props تو ری‌اکت چیکار می‌کنه؟
10 تفاوت state و props چیه؟
11 چرا نباید state رو مستقیما آپدیت کنیم؟
12 هدف از متدهای callback موقع استفاده از setState چیه؟
13 تفاوت بین نحوه مدیریت رویداد HTML و React چیه؟
14 چطوری متد یا event رو به تابع callback توی JSX bind کنیم؟
15 چطوری میشه یک مقدار رو به یه تابع callback یا eventHandler پاس بدیم؟
16 Synthetic events(رویدادهای مصنوعی) تو ری‌اکت کدوما هستن؟
17 عبارات شرطی درون خطی چیه؟
18 پارامترهای key چیکار می‌کنن و مزایای استفاده از اونا توی حلقه‌ها چیه؟
19 کاربرد refها چیه؟
20 چطوری از ref استفاده کنیم؟
21 forward ref چیه؟
22 بین callback refs و تابع findDOMNode کدوم رو ترجیح میدی؟
23 چرا Refهای متنی منقضی محسوب می‌شوند؟
24 Virtual DOM چیه؟
25 Virtual DOM چطوری کار می‌کنه؟
26 تفاوت بین Shadow DOM و Virtual DOM چیه؟
27 React Fiber چیه؟
28 هدف اصلی React Fiber چیه؟
29 کامپوننت‌های کنترل شده چی هستن؟
30 کامپوننت‌های کنترل نشده چی هستن؟
31 تفاوت‌های بین createElement و cloneElement کدوما هستن؟
32 مفهوم lift state up یا مدیریت state در لول بالاتر رو توضیح میدی؟
33 فازهای مختلف از lifecycle کامپوننت کدوما هستن؟
34 متدهای lifecycle کامپوننت کدوما هستن؟
35 کامپوننت‌های Higher-Order چی هستن؟
36 چطوری می‌تونیم props proxy برای کامپوننت‌های HOC ایجاد کنیم؟
37 context چیه؟
38 children prop چیه؟
39 چطوری میشه تو React کامنت نوشت؟
40 چرا توی کامپوننت‌های کلاس باید توی constructor تابع super رو با مقدار props صدا بزنیم؟
41 reconciliation چیه؟
42 چطوری با یه اسم داینامیک set state کنیم؟
43 یه اشتباه رایج برای مدیریت توابع eventها که باعث میشه با هر رندر توابع مجدد ساخته بشن چی هستش؟
44 تابع lazy که برای lazy load استفاده میشه رو می‌تونیم به صورت name export خروجی بگیریم؟
45 چرا ری‌اکت از className بجای class استفاده می‌کنه؟
46 fragmentها چی هستن؟
47 چرا fragmentها از تگ‌های div بهترن؟
48 توی ری‌اکت portal‌ها چیکار می‌کنن؟
49 کامپوننت stateless چیه؟
50 کامپوننت stateful چیه؟
51 چطوری prop‌های کامپوننت رو اعتبارسنجی کنیم؟
52 مزایای React چیه؟
53 محدودیت‌های React چیه؟
54 error boundaryها توی ری‌اکت نسخه 16 چیکار می‌کنن؟
55 چطوری از error boundaryها توی نسخه 15 ری‌اکت استفاده کنیم؟
56 روش‌های پیشنهادی برای type checking چیه؟
57 کاربرد پکیج react-dom چیه؟
58 کاربرد متد render از پکیج react-dom چیه؟
59 ReactDOMServer چیه؟
60 چطوری از InnerHtml توی ری‌اکت استفاده کنیم؟
61 چطوری توی ری‌اکت استایل‌دهی می‌کنیم؟
62 تفاوت eventهای ری‌اکت چیه؟
63 اگه توی constructor بیاییم و setState کنیم چی میشه؟
64 تاثیر استفاده از ایندکس به عنوان key چیه؟
65 نظرت راجع به استفاده از setState توی متد componentWillMount چیه؟
66 اگه از prop توی مقداردهی اولیه state استفاده کنیم چی میشه؟
67 چطوری کامپوننت رو با بررسی یه شریط رندر می‌کنیم؟
68 چرا وقتی propها رو روی یه DOM Elemnt می‌آییم spread می‌کنیم باید مراقب باشیم؟
69 چطوری از decoratorها توی ری‌اکت استفاده کنیم؟
70 چطوری یه کامپوننت رو memoize می‌کنیم؟
71 چطوری باید Server-Side Rendering یا SSR رو توی ری‌اکت پیاده کنیم؟
72 چطوری حالت production رو برای ری‌اکت فعال کنیم؟
73 CRA چیه و چه مزایایی داره؟
74 ترتیب اجرا شدن متد‌های life cycle چطوریه؟
75 کدوم متد‌های life cycle توی نسخه 16 ری‌اکت منسوخ شدن؟
76 کاربرد متد getDerivedStateFromProps چیه؟
77 کاربرد متد getSnapshotBeforeUpdate چیه؟
78 آیا هوک‌ها جای render props و HOC رو می‌گیرن؟
79 روش توصیه شده برای نام‌گذاری کامپوننت‌ها چیه؟
80 روش توصیه شده برای ترتیب متدها در کلاس کامپوننت‌ها چیه؟
81 کامپوننت تعویض کننده یا switching چیه؟
82 چرا نیاز میشه به تابع setState یه فانکشن callback پاس بدیم؟
83 حالت strict توی ری‌اکت چیکار می‌کنه؟
84 Mixin‌های ری‌اکت چی هستن؟
85 چرا isMounted آنتی پترن هست و روش بهتر انجامش چیه؟
86 پشتیبانی ری‌اکت از pointer eventها چطوریه؟
87 چرا باید اسم کامپوننت با حرف بزرگ شروع بشه؟
88 آیا propهای custom توی ری‌اکت پشتیبانی میشن؟
89 تفاوت‌های constructor و getInitialState چیه؟
90 می‌تونیم یه کامپوننت رو بدون setState ری‌رندر کنیم؟
91 تفاوت‌های فراخوانی super(-) و super(props) توی کلاس کامپوننت‌های ری‌اکت چیه؟
92 چطوری توی JSX حلقه یا همون لوپ رو داشته باشیم؟
93 توی attributeها چطوری به prop دسترسی داشته باشیم؟
94 چطوری یه PropType برای ‌آرایه‌ای از objectها با shape داشته باشیم؟
95 چطوری classهای یه المنت رو به صورت شرطی رندر کنیم؟
96 تفاوت‌های React و ReactDOM چیه؟
97 چرا ReactDOM رو از React جدا کردن؟
98 چطوری از label تو ری‌اکت استفاده کنیم؟
99 چطوری می‌تونیم چندتا object از استایل‌های درون خطی رو با هم ترکیب کنیم؟
100 چطوری با resize شدن مرورگر یه ویو رو ری‌رندر کنیم؟
101 تفاوت متدهای setState و replaceState چیه؟
102 چطوری به تغییرات state گوش بدیم؟
103 روش توصیه شده برای حذف یک عنصر از آرایه توی state چیه؟
104 امکانش هست که ری‌اکت رو بدون رندر کردن HTML استفاده کنیم؟
105 چطوری میشه با ری‌اکت یه JSON به شکل beautify شده نشون داد؟
106 چرا نمی‌تونیم prop رو آپدیت کنیم؟
107 چطوری می‌تونیم موقع لود صفحه روی یه input فوکوس کنیم؟
108 روش‌های ممکن برای آپدیت کردن object توی state کدوما هستن؟
109 چرا توابع به جای object در setState ترجیح داده می‌شوند؟
110 چطوری می‌‌تونیم نسخه ری‌اکت جاری رو توی محیط اجرایی بفهمیم؟
111 روش‌های لود کردن polyfill توی CRA کدوما هستن؟
112 توی CRA چطوری از https به‌جای http استفاده کنیم؟
113 توی CRA چطوری میشه از مسیر‌های طولانی برای ایمپورت جلوگیری کرد؟
114 چطوری میشه Google Analytics رو به react-router اضافه کرد؟
115 چطوری یه کامپوننت رو هر ثانیه به روز کنیم؟
116 برای استایل‌دهی‌های درون خطی چطوری باید پیشوند‌های مخصوص مرورگرها رو اضافه کرد؟
117 چطوری کامپوننت‌های ری‌اکت رو با es6 می‌تونیم import و export کنیم؟
118 استثنایی که برای نام‌گذاری کامپوننت اجازه استفاده از حرف کوچک رو میده چیه؟
119 چرا تابع سازنده کلاس کامپوننت یکبار صدا زده میشه؟
120 توی ری‌اکت چطوری مقدار ثابت تعریف کنیم؟
121 چطوری توی برنامه event کلیک شدن رو trigger کنیم؟
122 آیا استفاده از async/await توی ری‌اکت ممکنه؟
123 ساختار پوشه‌بندی معروف برا ری‌اکت چطوریه؟
124 پکیج‌های مشهور برای انیمیشن کدوما هستن؟
125 مزایای ماژول‌های style چیه؟
126 معروف‌ترین linterهای ری‌اکت کدوما هستن؟
127 چطوری باید توی کامپوننت درخواست api call بزنیم؟
128 render props چیه؟
رووتر ری‌اکت
129 React Router چیه؟
130 ارتباط React Router و کتابخونه history چیه؟
131 کامپوننت‌های router توی نسخه۴ کدوما هستن؟
132 هدف از متدهای push و replace توی history چیه؟
133 چطوری توی برنامه به route خاص جابجا بشیم؟
134 چطوری میشه query پارامترها رو توی ری‌اکت روتر نسخه۴ گرفت؟
135 دلیل خطای "Router may have only one child element" چیه؟
136 چطوری میشه به متد history.push پارامتر اضافه کرد؟
137 چطوری میشه صفحه ۴۰۴ ساخت؟
138 توی ری‌اکت روتر نسخه۴ چطوری میشه history رو گرفت؟
139 چطوری بعد از لاگین به شکل خودکار ریدایرکت کنیم؟
چند زبانگی در ری‌اکت
140 React-Intl چیه؟
141 اصلی‌ترین ویژگی‌های React Intl کدوما هستن؟
142 دو روش فرمت کردن توی React Intl کدوما هستن؟
143 چطوری از FormattedMessage به عنوان یه placeholder میشه استفاده کرد؟
144 چطوری میشه locale فعلی رو توی React Intl بدست آورد؟
145 چطوری با استفاده از React Intl یه تاریخ رو فرمت‌بندی کنیم؟
تست کردن ری‌اکت
146 توی تست ری‌اکت Shallow Renderer چیه؟
147 پکیج TestRenderer توی ری‌اکت چیه؟
148 هدف از پکیج ReactTestUtils چیه؟
149 Jest چیه؟
150 مزایای jest نسبت به jasmine کدوما هستن؟
151 یه مثال ساده از تست با jest بزن؟
React Redux
152 Flux چیه؟
153 Redux چیه؟
154 مبانی اصلی ریداکس کدوما هستن؟
155 کاستی‌های redux نسبت به flux کدوما هستن؟
156 تفاوت‌های mapStateToProps و mapDispatchToProps چی هست؟
157 توی ریدیوسر می‌تونیم یه actionی رو dispatch کنیم؟
158 چطوری میشه خارج از کامپوننت میشه store ریداکس دسترسی داشت؟
159 اشکالات پترن MVW کدوما هستن؟
160 تشابهی بین Redux و RxJS هست؟
161 چطوری میشه یه اکشن رو موقع لود dispatch کرد؟
162 چطوری از متد connect از پکیج react-redux استفاده می‌کنیم؟
163 چطوری میشه state ریداکس رو ریست کرد؟
164 هدف از کاراکتر @ توی decorator متد connect چیه؟
165 تفاوت‌های context و React Redux چیه؟
166 چرا به توابع state ریداکس reducer میگن؟
167 توی redux چطوری میشه api request زد؟
168 آیا لازمه همه state همه کامپوننت‌هامونو توی ریداکس نگهداری کنیم؟
169 روش صحیح برای دسترسی به store ریداکس چیه؟
170 تفاوت‌های component و container توی ریداکس چی هست؟
171 هدف از constantها تا typeها توی ریداکس چیه؟
172 روش‌های مختلف برای نوشتن mapDispatchToProps چیه؟
173 کاربرد پارامتر ownProps توی mapStateToProps و mapDispatchToProps چیه؟
174 ساختار پوشه‌بندی ریشه ریداکس اکثرا چطوریه؟
175 redux-saga جیه؟
176 مدل ذهنی redux-saga چطوریه؟
177 تفاوت افکت‌های call و put توی redux-saga چی هست؟
178 Redux Thunk چیه؟
179 تفاوت‌های redux-saga و redux-thunk چیا هستن؟
180 Redux DevTools چیه؟
181 ویژگی‌های Redux DevTools کدوما هستن؟
182 سلکتورهای ریداکس چی هستن و چرا باید ازشون استفاده کنیم؟
183 Redux Form چیه؟
184 اصلی‌ترین ویژگی‌های Redux Form چیه؟
185 چطوری میشه چندتا middleware به ریداکس اضافه کرد؟
186 چطوری میشه توی ریداکس initial state تعریف کرد؟
187 تفاوت‌های Relay با Redux کدوما هستن؟
React Native
188 تفاوت‌های React Native و React کدوما هستن؟
189 چطوری میشه برنامه React Native رو تست کرد؟
190 چطوری میشه توی React Native لاگ کرد؟
191 چطوری میشه React Native رو دیباگ کرد؟
کتابخانه‌های مورد استفاده با ری‌اکت
192 کتابخونه reselect چیه و چطوری کار می‌کنه؟
193 Flow چیه؟
194 تفاوت‌های Flow و PropTypes کدوما هستن؟
195 چطوری از آیکون‌های font-awesome توی ری‌اکت استفاده کنیم؟
196 React Dev Tools چیه؟
197 چرا توی کروم devtools برای فایل‌های local لود نمیشه؟
198 چطوری از Polymer توی React استفاده کنیم؟
199 مزایای React نسبت به Vue.js کدوما هستن؟
200 تفاوت‌های React و Angular کدوما هستن؟
201 چرا تب React در DevTools نشان داده نمی‌شود؟
202 Styled components چیه؟
203 یه مثال از Styled Components می‌تونی بگی؟
204 Relay چیه؟
205 چطوری میشه از تایپ اسکریپت توی create-react-app استفاده کرد؟
متفرقه
206 اصلی‌ترین ویژگی‌های کتابخونه reselect کدوما هستن؟
207 یه مثال از کارکرد کتابخونه reselect بزن؟
208 توی Redux اکشن چیکار می‌کنه؟
209 استاتیک شی با کلاس‌های ES6 در React کار می کنه؟
210 ریداکس رو قفط با ری‌اکت میشه استفاده کرد؟
211 برای استفاده از Redux به ابزار build خاصی احتیاج داریم؟
212 مقادیر پیش‌فرض ریداکس فرم چطوری تغییرات رو از state می‌گیرن؟
213 توی PropTypeهای ری‌اکت چطوری میشه برای یه prop چند نوع داده مجاز مشخص کرد؟
214 می‌تونیم فایل svg رو به عنوان کامپوننت import کنیم؟
215 چرا استفاده از توابع ref callback درون خطی توصیه نمیشه؟
216 render hijacking توی ری‌اکت چیه؟
217 پیاده‌سازی factory یا سازنده HOC چطوریه؟
218 چطوری به یه کامپوننت ری‌اکت عدد پاس بدیم؟
219 لازمه همه stateها رو توی ریداکس مدیریت کنیم؟ لزومی به استفاده از state داخلی داریم؟
220 هدف از متد registerServiceWorker توی ری‌اکت چیه؟
221 چطوری با استفاده از تابع setState از رندر غیرضروری جلوگیری کنیم؟
222 توی نسخه ۱۶ ری‌اکت چطوری میشه آرایه، Strings و یا عدد رو رندر کنیم؟
223 hookها چی هستن؟
224 چه قوانینی برای هوک‌ها باید رعایت بشن؟
225 چطوری میشه از استفاده درست هوک‌ها اطمینان حاصل کرد؟
226 تفاوت‌های Flux و Redux کدوما هستن؟
227 مزایای ری‌اکت روتر نسخه۴ چیه؟
228 می‌تونی راجع به متد componentDidCatch توضیح بدی؟
229 در چه سناریویی error boundary خطا رو catch نمی‌کنه؟
230 چرا نیازی به error boundaries برای event handlerها نیست؟
231 تفاوت بلوک try catch و error boundaryها چیه؟
232 رفتار خطاهای uncaught در ری‌اکت 16 چیه؟
233 محل مناسب برای قرار دادن error boundary کجاست؟
234 مزیت چاپ شدن stack trace کامپوننت‌ها توی متن ارور boundary ری‌اکت چیه؟
235 متدی که در تعریف کامپوننت‌های class الزامیه؟
236 نوع‌های ممکن برای مقدار بازگشتی متد render کدوما هستن؟
237 هدف اصلی از متد constructor چیه؟
238 آیا تعریف متد سازنده توی ری‌اکت الزامیه؟
239 Default propها چی هستن؟
240 چرا نباید تابع setState رو توی متد componentWillUnmount فراخوانی کرد؟
241 کاربرد متد getDerivedStateFromError چیه؟
242 کدوم متدها و به چه ترتیبی در طول ری‌رندر فراخوانی میشن؟
243 کدوم متد‌ها موقع error handling فراخوانی میشن؟
244 کارکرد ویژگی displayName چیه؟
245 پشتیبانی مرورگرها برای برنامه ری‌اکتی چطوریه؟
246 هدف از متد unmountComponentAtNode چیه؟
247 code-splitting چیه؟
248 مزایای حالت strict چیه؟
249 Fragmentهای دارای key هستن؟
250 آیا ری‌اکت از همه‌ی attributeهای HTML پشتیبانی می‌کنه؟
251 محدودیت‌های HOCها چی هستن؟
252 چطوری میشه forwardRefs رو توی DevTools دیباگ کرد؟
253 مقدار یه props کامپوننت کی true میشه؟
254 NextJS چیه و ویژگی‌های اصلیش کدوما هستن؟
255 چطوری می‌تونیم یه تابع event handler رو به یه کامپوننت پاس بدیم؟
256 استفاده از توابع arrow برای متدهای render خوبه؟
257 چطوری از اجرای چندباره یه تابع جلوگیری کنیم؟
258 JSX چطوری از حمله‌های Injection جلوگیری می‌کنه؟
259 چطوری elementهای رندر شده رو آپدیت کنیم؟
260 چرا propها read only هستن؟
261 چرا میگیم تابع setState از طریق merge کردن state را مدیریت می‌کنه؟
262 چطوری می‌تونیم به متد event handler پارامتر پاس بدیم؟
263 چطوری از رندر مجدد کامپوننت‌ها جلوگیری کنیم؟
264 شرایطی که بدون مشکل پرفورمنس بتونیم از ایندکس به عنوان key استفاده کنیم چی هست؟
265 keyهای ری‌اکت باید به صورت عمومی منحصر بفرد باشن؟
266 گزینه‌های محبوب برای مدیریت فرم‌ها توی ری‌اکت کدوما هستن؟
267 مزایای کتابخانه فرمیک نبست به redux form چیه؟
268 چرا اجباری برای استفاده از ارث‌بری توی ری‌اکت نیست؟ مزیتی داره؟
269 می‌تونیم از web components توی برنامه ری‌اکت استفاده کنیم؟
270 dynamic import چیه؟
271 loadable componentها چی هستن؟
272 کامپوننت suspense چیه؟
273 چطوری به ازای route می‌تونیم code splitting داشته باشیم؟
274 یه مثال از نحوه استفاده از context میزنی؟
275 هدف از مقدار پیش‌فرض توی context چیه؟
276 چطوری از contextType استفاده می‌کنین؟
277 consumer چیه؟
278 چطوری مسائل مربوط به پرفورمنس با context رو حل می‌کنین؟
279 هدف از forward ref توی HOCها چیه؟
280 توی کامپوننت‌ها می‌تونیم پراپ ref داشته باشیم؟
281 چرا در هنگام استفاده از ForwardRefها نیاز به احتیاط بیشتری در استفاده از کتابخانه‌های جانبی داریم؟
282 چطوری بدون استفاده از ES6 کلاس کامپوننت بسازیم؟
283 استفاده از ری‌اکت بدون JSX ممکن است؟
284 الگوریتم‌های diffing ری‌اکت چی هستن؟
285 قوانینی که توسط الگوریتم‌های diffing پوشش داده می‌شوند کدام هستن؟
286 چه موقعی نیاز هست که از refها استفاده کنیم؟
287 برای استفاده از render propها لازمه که اسم prop رو render بزاریم؟
288 مشکل استفاده از render props با pure componentها چیه؟
289 چطوری با استفاده از render props می‌تونیم HOC ایجاد کنیم؟
290 تکنیک windowing چیه؟
291 توی JSX یه مقدار falsy رو چطوری چاپ کنیم؟
292 یه مورد استفاده معمول از portals مثال میزنی؟
293 توی کامپوننت‌های کنترل نشده چطوری مقداری پیش فرض اضافه کنیم؟
294 stack موردعلاقه شما برای کانفیگ پروژه ری‌اکت چیه؟
295 تفاوت‌ DOM واقعی و Virtual DOM چیه؟
296 چطوری Bootstrap رو به یه برنامه ری‌اکتی اضافه کنیم؟
297 می‌تونی یه لیستی از معروف‌ترین وب‌سایت‌هایی که از ری‌اکت استفاده می‌کنن رو بگی؟
298 استفاده از تکنیک CSS In JS تو ری‌اکت توصیه میشه؟
299 لازمه همه کلاس کامپوننت‌ها رو تبدیل کنیم به هوک؟
300 چطوری میشه با هوک‌های ری‌اکت دیتا fetch کرد؟
301 هوک‌ها همه موارد کاربرد کلاس‌ها رو پوشش میده؟
302 نسخه پایدار ری‌اکت که از هوک پشتیبانی می‌کنه کدومه؟
303 چرا از حالت destructuring آرایه برای useState استفاده می‌کنیم؟
304 منابعی که باعث معرفی ایده هوک‌ها شدن کدوما بودن؟
305 چطوری به APIهای ضروری اجزای وب دسترسی پیدا کنیم؟
306 formik چیه؟
307 middlewareهای مرسوم برای مدیریت ارتباط‌های asynchronous توی Redux کدوما هستن؟
308 مرورگرها کد JSX رو متوجه میشن؟
309 Data flow یا جریان داده ری‌اکت رو توضیح میدی؟
310 react scripts چیه؟
311 ویژگی‌های create react app چیه؟
312 هدف از متد renderToNodeStream چیه؟
313 MobX چیه؟
314 تفاوت‌های بین Redux و MobX کدوما هستن؟
315 لازمه قبل از شروع ری‌اکت ES6 رو یاد گرفت؟
316 Concurrent Rendering چیه؟
317 تفاوت بین حالت async و concurrent چیه؟
318 می‌تونیم از آدرس‌های دارای url جاواسکریپت در ری‌اکت 16.9 استفاده کنیم؟
319 هدف از پلاگین eslint برای هوک‌ها چیه؟
320 تفاوت‌های Imperative و Declarative توی ری‌اکت چیه؟
321 مزایای استفاده از تایپ اسکریپت با ری‌اکت چیه؟

پیشگفتار

در ابتدا، ممنونم از شما که با خرید این کتاب بهمون کمک کردین که بتونیم قدمی در راه کمک به افراد نیازمند برداریم و با درآمد حاصل از فروش این کتاب کمکی هر چند کوچیک در راه مسئولیت اجتماعی‌مون برداریم، به هم‌دیگه کمک کنیم، با هم مهربون‌تر باشیم و در کنار هم پیشرفت کنیم. تشکر گرم من رو، دورادور پذیرا باشین و امیدوارم این کتاب به جهت افزایش دانش‌تون و کمک به پیشرفت شغلی‌تون کمکی کرده باشه.
کتابی که پیش‌روی شماست، حاصل تلاش نه فقط من، بلکه چندین نفر از بهترین و حرفه‌ای‌ترین دوستان بنده هم هست که در اینجا به ترتیب میزان زحمتی که متقبل شدن اسمشونو قید می‌کنم و کمال تشکر رو ازشون دارم:

  • مهسا مصباح

  • امین آشتیانی

  • مهدی رحیمی

این عزیزان هر کدام با کمک‌هاشون برای ترجمه، ویراستاری‌هاشون و حتی دل‌گرمی‌هاشون باعث شدن این مجموعه به زبان فارسی آماده بشه و به شکل چاپی بتونه به دستان شما برسه.

ماریوتک

من جعفررضائی، پلتفرم ماریوتک رو با هدف آموزش اصولی و رایگان، تاسیس کردم و این کتاب هم از مجموعه ماریوتک منتشر میشه. ما ماریوتک رو متعلق به همه می‌دونیم، پس اگه بعضی تایم‌های بیکاری داری که فکر می‌کنی می‌تونی باهامون توی این مسیر همراه باشی حتما بهم ایمیل بزن. ایده‌های ماریوتک برای افزایش آگاهی و دانش تا حد امکان رایگان خواهد بود و تا به اینجا هم، تنها هزینه‌های چاپ برداشته شده و مابقی به موسسات خیریه داده شدن.

مطالب کتاب

مطالب این کتاب می‌تونن تا حد بسیار خوبی دانش شما رو توی مسائل کلیدی مربوط به React.js و کتابخونه‌های پیرامون اون افزایش بدن. سوالات چالشی و کلیدی مطرح شده توی کتاب اکثرا سوالاتی هستند که توی مصاحبه‌های استخدامی پرسیده میشن و مسلط بودن به اونا می‌تونه شانس موفقیت شما برای موقعیت‌های شغلی که مدنظر دارین افزایش بده. مطالب این کتاب به دلیل ترجمه بودن تا حد زیادی قابل دستکاری نبودن و سعی شده تا حد امکان حق گردآورنده محفوظ باشه و با نسخه اصلی سورس که توسط Sudheer Jonna جمع‌آوری شده تفاوت معنایی نداشته باشه. بخشی از مطالب کتاب اصلی به خاطر قدیمی بودن منقضی شده بودن و به عنوان مترجم بخش‌های زیادی از نمونه کدها و مطالب قدیمی تصحیح شدند. در آخر، امیدوارم همیشه شاد و خندان و خوشحال باشین. مخلصیم

هسته ری‌اکت

  1. ری‌اکت چیه؟

    ری‌اکت یه کتابخونه متن‌باز هست که برای ساختن رابط کاربری به خصوص برنامه‌های تک صفحه‌ای استفاده میشه. از این کتابخونه برای مدیریت لایه view توی برنامه‌های وب و موبایل استفاده میشه. توسط Jordan Walke تولید شده که یه مهندس نرم‌افزار توی شرکت فیس‌بوک هستش. اولین بار سال ۲۰۱۱ و روی برنامه اینستاگرام مورد استفاده قرار گرفت.

    فهرست

  2. اصلی‌ترین ویژگی‌های ری‌اکت کدوما هستن؟

    اصلی‌ترین ویژگی‌های ری‌اکت اینا هستن:

    • از VirtualDOM به جای RealDOM استفاده‌می‌کنه چون هزینه تغییرات RealDOM زیاده (یعنی پیدا کردن DOM Element و حذف یا به روز رسانی با سرعت کمتری انجام میشه)

    • از SSR یا همون Server Side Rendering پشتیبانی ‌می‌کنه

    • از جریان داده‌ها یا data binding به صورت یک طرفه (unidirectional) پیروی‌ می‌کنه

    • برای توسعه view از UI کامپوننت‌های reusable/composable استفاده ‌می‌کنه

    فهرست

  3. JSX چیه؟

    JSX یه افزونه با سینتکسی شبیه به XML برای ECMAScript است (مخفف Javascript XML). اگه بخوایم ساده بگیم وظیفه اش اینه که سینتکسی ساده تر از React.createElement دراختیارتون قرار میده، شما می‌تونین Javascript رو در کنار ساختاری شبیه به HTML داشته باشید.

    تو مثال زیر می‌بینید که نوشته داخل تگ h1 مثل یک تابع Javascript به تابع render تحویل داده میشه.

    1. function component

    class App extends React.Component {
      render() {
        return (
          <div>
            <h1>{"Welcome to React world!"}</h1>
          </div>
        );
      }
    }
    
    1. class component

    class App extends React.Component {
      render() {
        return (
          <div>
            <h1>{"Welcome to React world!"}</h1>
          </div>
        );
      }
    }
    

    فهرست

  4. تفاوت‌های Element و Component چیه؟

    Element یک شی ساده است که وظیفه داره اون چیزی که روی صفحه نمایش داده میشه رو توصیف کنه، حالا ممکنه به صورت یک DOM node باشه یا به صورت componentهای دیگه. Element ها می‌تونن شامل Elements های دیگه به عنوان props باشند. ساختن یک Element در React کار ساده و کم دردسریه اما وقتی که ساخته شد هیچ وقت نمیشه تغییرش داد.

    تو مثال زیر یک شی که توسط React Element ساخته شده رو میبینیم:

    const element = React.createElement("div", { id: "login-btn" }, "Login");
    

    تابع React.createElement که توی قطعه کد بالا میبینید یه object شبیه به این برمی‌گردونه:

    {
      type: 'div',
      props: {
        children: 'Login',
        id: 'login-btn'
      }
    }
    

    و آخرش هم با استفاده از ReactDOM.render می‌تونیم توی DOM , Render کنیم

    <div id="login-btn">Login</div>
    

    درحالیکه یه component می‌تونه به روشهای مختلفی ساخته بشه. می‌تونه یه class باشه با یه متد render. یا حتی به عنوان یه جایگزین ساده‌تر به صورت یک تابع تعریف بشه. در هر دو حالت کامپوننت ساخته شده props رو به عنوان ورودی دریافت‌ می‌کنه و یه خروجی رو به صورت یه JSX tree برمی‌گردونه. به مثال زیر دقت کنیم که چطور با استفاده از یه تابع و JSX یک کامپوننت ساخته میشه:

    const Button = ({ onLogin }) => (
      <div id={"login-btn"} onClick={onLogin}>
        Login
      </div>
    );
    

    JSX به React.createElement ترنسپایل (transpile) میشه:

    const Button = ({ onLogin }) =>
      React.createElement(
        "div",
        { id: "login-btn", onClick: onLogin },
        "Login"
      );
    

    فهرست

  5. تو ری‌اکت چطوری کامپوننت می‌سازیم؟

    تو سوال قبل یه اشاره کوچیک کردیم که دوتا راه برای ساختن کامپوننت وجود داره.
    ۱. Function Components: این ساده‌ترین راه برای ساختن یه کامپوننته. یه Pure Javascript Function رو در نظر بگیرید که Props که خودش یه object هست رو به عنوان پارامتر ورودی میگیره و یه React Element به عنوان خروجی برمی‌گردونه مثل همین مثال پایین:

    function Greeting({ message }) {
      return <h1>{`Hello, ${message}`}</h1>;
    }
    

    ۲. Class Components: شما می‌تونین از class که در ES6 به جاواسکریپت اضافه شده برای این کار استفاده کنیم. کامپوننت مثال قبلی رو اگه بخواییم با class پیاده سازی کنیم اینجوری میشه:

    class Greeting extends React.Component {
      render() {
        return <h1>{`Hello, ${this.props.message}`}</h1>;
      }
    }
    

    فقط یادتون نره تو این روش متدrender یه جورایی required میشه.

    فهرست

  6. کی باید از Class Component بجای Function Component استفاده کنیم؟

    میشه گفت هیچ لزومی به این‌کار نیست(مگر در مواقع خیلی خاص مثل error boundaryها) و از ورژن 16.8 ری‌اکت به بعد و با اضافه شدن هوک‌ها به فانکشن کامپوننت‌ها، شما می‌تونین از state یا lifecycle methodها یا تمامی فیچرهایی که قبلا فقط در کلاس کامپوننت ‌ها قابل استفاده بود، توی فانکشن کامپوننت‌هاتون استفاده کنین.
    ولی قبلا اگه کامپوننت نیاز به state یا lifecycle methods داشت از کلاس کامپوننت‌ها باید استفاده می‌کردیم و در غیر این صورت می‌رفتیم سراغ فانکشن کامپوننت‌ها.

    فهرست

  7. Pure Components چیه؟

    برای اینکه ری‌رندر شدن یه کامپوننت رو کنترل کنیم، توی کلاس کامپوننت‌ها بجای Component از PureComponent کامپوننت‌مون رو می‌ساختیم، در حقیقت PureComponent دقیقا مثل Component می‌مونه فقط تنها تفاوتی که داره اینه که برخلاف Component خودش به صورت خودکار متد shouldComponentUpdate رو هندل‌می‌کنه.
    وقتی که props یا state در کامپوننت تغییر‌می‌کنه، PureComponent یه مقایسه سطحی روی props و state انجام میده (shallow comparison) در حالیکه Component این مقایسه رو به صورت خودکار انجام نمیده و به طور پیش‌فرض کامپوننت هربار که shouldComponentUpdate فراخوانی بشه re-render میشه. بنابراین توی Component باید این متد override بشه.
    برای انجام این‌کار روی فانکشن کامپوننت‌ها، میشه از React.memo استفاده کرد.

    فهرست

  8. state تو ری‌اکت چیکار می‌کنه؟

    State در هر کامپوننت بسته به کلاس کامپوننت بودن یا فانکشن بودن نوع متفاوتی داره، مثلا در کلاس کامپوننت‌ها state یه آبجکته که یه سری اطلاعات که در طول عمر کامپوننت ما ممکنه تغییر کنه رو در خودش ذخیره‌می‌کنه. ما باید تمام تلاشمون رو بکنیم که state‌مون در ساده ترین حالت ممکن باشه و تاجایی که می‌تونیم تعداد کامپوننت‌هایی که stateful هستن رو کاهش بدیم. به عنوان مثال بیایید یه کامپوننت User رو که یه state داره بسازیم:

    1. function

    const User = () => {
      const [message, setMessage] = useState('Hello react world!');
    
      return (
        <div>
          <h1>{message}</h1>
        </div>
      );
    }
    
    1. class

    class User extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          message: "Welcome to React world",
        };
      }
    
      render() {
        return (
          <div>
            <h1>{this.state.message}</h1>
          </div>
        );
      }
    }
    

    state

    State و Props بهم شبیه هستن ولی Stateها کاملا در کنترل کامپوننت هستن و فقط مختص به همون کامپوننت هستن(private). یعنی state ‌ها در هیچ کامپوننتی به غیر از اونی که مالکstate هست در دسترس نخواهند بود.

    فهرست

  9. props تو ری‌اکت چیکار می‌کنه؟

    _Prop_ها ورودی کامپوننت‌ها هستن. می‌تونن یه مقدار ساده یا یه object شامل یه مجموعه مقدار باشن که در لحظه ایجاد کامپوننت و بر اساس یه قاعده نام گذاری که خیلی شبیه به attributeهای HTML هست، به کامپوننت پاس داده میشن. در واقع این مقادیر، داده‌هایی هستن که از کامپوننت پدر به فرزند تحویل داده میشن.

    هدف اصلی وجود Props در ری‌اکت ایجاد ساختارهای زیر در یک کامپوننت‌ـه، به طورکلی میشه گفت که هدفشون:

    1 - پاس دادن مقادیر به کامپوننت‌های فرزند.

    2 - پاس دادن متد تغییر state و trigger کردن اون متد در زمان تغییر دلخواه.

    3 - استفاده از اونا برای پاس دادن jsx و رندر کردن یه المنت دلخواه داخل یه کامپوننت دیگه.

    به عنوان مثال، یه کامپوننت با استفاده ازrenderProp میسازیم:

    <Element renderProp={<span>Hi there</span>} />
    

    این renderProp(یا هرچیز دیگه‌ای که شما می‌تونین اسمشو بزارین) در نهایت تبدیل به یک property خواهد شد که داخل props ورودی کامپوننت به شکل object قابل دسترس هست.

    const Element = (props) => {
      return <div>
        {props.renderProp}
      </div>
    }
    

    توی کامپوننت بالا یه jsx با prop به کامپوننت Element داده میشه و توی اون رندر میشه 😃

    فهرست

  10. تفاوت state و props چیه؟

    هر دوتاشون javascript plain object هستن، یعنی یه object که یه سری property داره که به یه سری مقدار ختم میشن و خبری از فانکشن و چیزهای دیگه روی این object وجود نداره(تقریباِ). هردوتاشون وظیفه دارن مقادیری که روی render تاثیر گذار هست رو نگه‌داری کنن اما عملکردشون با توجه به کامپوننت متفاوت خواهد بود. Props شبیه به پارامترهای ورودی یک فانکشن، به کامپوننت پاس داده میشن در حالیکه state شبیه به متغییرهایی که داخل فانکشن ساخته شدن، توسط خود کامپوننت ایجاد و مدیریت میشه.

    فهرست


  1. چرا نباید state رو مستقیما آپدیت کنیم؟

    اگه یه بار تلاش کنید که مستقیما state رو آپدیت کنید متوجه می‌شین که کامپوننت شما مجددا render نمیشه.

    // Wrong
    let [message, setMessage] = useState('test');
    message = "Hello world";
    

    به جای اینکه مستقیما state رو آپدیت کنیم باید از متد setState در Class Component و از useState در Function Components استفاده کنیم. این متدها یک آپدیت در شی state رو برنامه ریزی و مدیریت می‌کنن و وقتی تغییر انجام شد کامپوننت شما re-render خواهد شد.

    const [message, setMessage] = React.useState("Hello world");
    
    setMessage("New Hello world");
    

    فهرست

  2. هدف از متدهای callback توی استفاده از setState چیه؟

    توی کلاس کامپوننت‌ها میشه بعد از انجام شدن یه setState، یه کار خاص دیگه‌ای رو توی callback انجام داد.
    callback function زمانی که setState تموم شد و کامپوننت مجددا render شد فراخوانی میشه. از اونجایی که setState به شکل asynchronous یا همون غیرهمزمان اجرا میشه از callback برای کارهایی استفاده میشه که بعد از تابع setState قراره اجرا بشن.

    نکته مهم: بهتره که به جای callback از lifecycle متد‌ها استفاده کنیم.

    setState({ name: "John" }, () =>
      console.log("The name has updated and component re-rendered")
    );
    

    این سازوکار رو، میشه روی فانکشن کامپوننت‌ها با یه کاستوم هوک به شکل زیر پیاده‌سازی کرد:

    function useStateCallback(initialState) {
        const [state, setState] = useState(initialState);
        const cbRef = useRef(null); // mutable ref to store current callback
        
        const setStateCallback = useCallback((state, cb) => {
            cbRef.current = cb; // store passed callback to ref
            setState(state);
        }, []);
        
        useEffect(() => {
            // cb.current is `null` on initial render, so we only execute cb on state *updates*
            if (cbRef.current) {
                cbRef.current(state);
                cbRef.current = null; // reset callback after execution
            }
        }, [state]);
        
        return [state, setStateCallback];
    }
    

    یه کم پیچیده به نظر میرسه ولی خب می‌تونه یه هوک خیلی کاربردی باشه. به شکل زیر هم ازش استفاده می‌کنیم:

    const App = () => {
        const [state, setState] = useStateCallback(0); // same API as useState + setState with cb
        
        const handleClick = () => {
            setState(
                prev => prev + 1,
                // 2nd argument is callback , `s` is *updated* state
                s => console.log("I am called after setState, state:", s)
            );
        };
        
        return <button onClick={handleClick}>Increment</button>;
    }
    

    فهرست


  1. تفاوت بین نحوه مدیریت رویداد HTML و React چیه؟

    1. توی HTML، عنوان رخداد حتما باید با حرف کوچیک شروع بشه یا اصطلاحا lowercase باشه:

    <button onclick="activateLasers()"></button>
    

    ولی توی ری‌اکت از camelCase پیروی می‌کنه:

    <button onClick={activateLasers}>Test</button>
    
    1. توی HTML می‌تونیم برای جلوگیری از اجرای رفتار پیش‌فرض(preventDefault) یه مقدار false برگرودونیم:

    <a href="#" onclick='console.log("The link was clicked."); return false;' />
    

    ولی توی ری‌اکت برای انجام این مورد حتما باید از preventDefault استفاده بشه:

    function handleClick(event) {
      event.preventDefault();
      console.log("The link was clicked.");
    }
    
    1. توی HTML برای اجرای تابع حتما باید اونو با گذاشتن پرانتزهایی که بعد اسمش میزاریم invoke کنیم()
      ولی توی ری‌اکت اجباری به گذاشتن () جلوی اسم تابع نیست.(برای مثال به کد اول و تابع "activateLasers" دقت کنید)

    فهرست

  2. چطوری متد یا event رو به تابع callback توی JSX bind کنیم؟

    توی کلاس کامپوننت‌ها به سه روش مختلف می‌تونیم this رو به تابع هندلر موردنظرمون bind کنیم:

    1. Bind کردن توی Constructor: توی کلاس‌های جاواسکریپتی متدها به صورت پیش‌فرض bound نمیشن. همین موضوع توی کلاس کامپوننت‌های ری‌اکتی برای متدهای موجود هم رخ میده که اکثرا توی متد سازنده یا همون constructor می‌آییم bind می‌کنیم.

    class Component extends React.Componenet {
      constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        //...
      }
    }
    
    1. استفاده از فیلد عمومی کلاس(public): اگه از روش اول خوشتون نمیاد این روش هم می‌تونه context درست رو موقع callbackها براتون فراهم کنه.

    handleClick = () => {
      console.log("this is:", this);
    };
    
    <button onClick={this.handleClick}>{"Click me"}</button>
    
    1. توابع arrow توی callback: می‌تونین از توابع arrow به شکل مستقیم توی callbackها استفاده کنین.

    <button onClick={(event) => this.handleClick(event)}>{"Click me"}</button>
    

    نکته: اگه متد‌های callback به عنوان prop به کامپوننت‌های فرزندشون پاس داده بشن، ممکنه اون کامپوننت‌ها re-renderingهای ناخواسته‌ای داشته باشن. توی اینگونه موارد روش توصیه شده استفاده از .bind یا فیلد عمومی کلاس برای مدیریت پرفورمنس هستش.

    فهرست

  3. چطوری میشه یک مقدار رو به یه تابع callback یا eventHandler پاس بدیم؟

    می‌تونیم از توابع arrow استفاده کنیم که با wrap کردن دور event handler و پاس دادن مقدار موردنظرمون بهش کارمونو انجام بدیم:

    const handleClick = (id) => {
      console.log("Hello, your ticket number is", id);
    };
    
    return users.map(user => <button onClick={() => handleClick(user.id)}>Test</button>);
    

    جدا از این روش‌ها، میشه با ایجاد یه curry، یه تابع دیگه دور تابع هندلر خودمون wrap کنیم و پارامتر رو به اون پاس بدیم:

    const handleClick = (id) => () => {
      console.log("Hello, your ticket number is", id);
    };
    
    return users.map(user => <button onClick={handleClick(user.id)} />);
    

    فهرست

  4. Synthetic events(رویدادهای مصنوعی) تو ری‌اکت کدوما هستن؟

    SyntheticEvent یه رخداد cross-browser هست که به‌عنوان یه wrapper دور eventهای اصلی مرورگر قرار می‌گیره. رابط API برای کارکردن با اون دقیقا مثل رخداد native مرورگرهاست که شامل stopPropagation و preventDefault میشه، با این تفاوت که این رخداد‌ها بر روی همه مرورگرها کار می‌کنن.

    فهرست

  5. عبارات شرطی درون خطی چیه؟

    برای بررسی یه شرط می‌تونیم از عبارت شرطی if استفاده کنیم، البته عملگرهای درون خطی سه‌گانه(ternary) هم میشه استفاده کرد که از ویژگی‌های خود js هستن. جدا از این ویژگی‌ها، ‌می‌تونیم هر عبارتی داخل آکولاد و توی JSX به اصطلاح embed یا ترکیب کنیم و با عملگر منطقی && ترکیب کنیم، مثال پایینی رو ببنید:

    <h1>Hello!</h1>;
    {
      messages.length > 0 && !isLogin ? (
        <h2>You have {messages.length} unread messages.</h2>
      ): (
        <h2>You don't have unread messages.</h2>
      );
    }
    

    فهرست

  6. پارامترهای key چیکار می‌کنن و مزایای استفاده از اونا توی حلقه‌ها چیه؟

    پارامتر key یه attribute ویژه است و موقعی که داریم یه آرایه از المان‌ها رو ایجاد می‌کنیم این پارامتر رو باید بهشون به عنوان prop بدیم. Keyها به ری‌اکت کمک می‌کنن که بدونه باید کدوم اِلمان رو دقیقا اضافه، حذف یا به روز کنه.

    اکثرا از ID یا از یه دیتای یونیک به عنوان key استفاده می‌کنن:

    const todoItems = todos.map((todo) => <li key={todo.id}>{todo.text}</li>);
    

    مواقعی که یه آی‌دی خاص برای المان‌ها نداریم، ممکنه بیایید و از اندیس یا همون index به عنوان key استفاده کنید:

    const todoItems = todos.map((todo, index) => (
      <li key={index}>{todo.text}</li>
    ));
    

    نکته:

    1. استفاده از indexها برای key توصیه نمیشه چون ممکنه ترتیب عناصر خیلی راحت عوض بشه و این می‌تونه پرفورمنس برنامه رو تحت تاثیر بزاره.

    2. اگه بیایین و لیست مورد نظر رو به جای li مثلا با یه کامپوننت به اسم ListItem جایگزین کنین و prop موردنظر key رو به جای li به اون پاس بدیم، یه warning توی کنسول خواهیم داشت که میگه key پاس داده نشده.

    فهرست


  1. کاربرد refها چیه؟

    ref به عنوان یه مرجع برای دسترسی مستقیم به اِلمان موردنظرمون استفاده میشه. تا حد امکان و توی اکثر مواقع بهتره از اونا استفاده نکنیم، البته خیلی می‌تونن کمک کننده باشن چون دسترسی مستقیمی به DOM element یا instance اصلی component بهمون میدن.

    فهرست

  2. چطوری از ref استفاده کنیم؟

    دو تا روش وجود داره:

    1. استفاده از React.createRef و پاس دادن اون به element مورد نظرمون با attributeref.

    const Component = () => {
      const myRef = React.createRef();
    
      return <div ref={myRef} />;
    };
    
    1. اگه از نسخه ۱۶.۸ به بالاتر هم استفاده می‌کنیم که یه هوک به اسم useRef هست و می‌تونیم به سادگی توی کامپوننت‌های تابعی ازش استفاده کنیم. مثل:

    const RenderCounter = () => {
      const counter = useRef(0);
    
      // Since the ref value is updated in the render phase,
      // the value can be incremented more than once
      counter.current = counter.current + 1;
    
      return <h1>{`The component has been re-rendered ${counter} times`}</h1>;
    };
    

    فهرست

  3. forward ref چیه؟

    Ref forwarding ویژگی‌ایه که به بعضی از کامپوننت‌ها این اجازه رو میده ref دریافت شده رو به کامپوننت فرزند انتقال بدن.

    const ButtonElement = React.forwardRef((props, ref) => (
      <button ref={ref} className="CustomButton">
        {props.children}
      </button>
    ));
    
    // Create ref to the DOM button:
    const ref = React.createRef();
    <ButtonElement ref={ref}>{"Forward Ref"}</ButtonElement>;
    

    فهرست

  4. بین callback refs و تابع findDOMNode کدوم رو ترجیح میدی؟

    ترجیح اینه که از callback refs به جای findDOMNode استفاده کنیم، چون findDOMNode از توسعه‌ کدهای ری‌اکت در آینده جلوگیری‌می‌کنه و ممکنه خطاهای ناخواسته ایجاد کنه.

    رویکرد قدیمی استفاده از findDOMNode:

    class MyComponent extends Component {
      componentDidMount() {
        findDOMNode(this).scrollIntoView();
      }
    
      render() {
        return <div></div>;
      }
    }
    

    رویکرد توصیه شده:

    const MyComponent = () => {
      const nodeRef = useRef();
      useEffect(() => {
        nodeRef.current.scrollIntoView();
      }, []);
      
      return <div ref={nodeRef} />;
    }
    

    فهرست


  1. چرا Refهای متنی منقضی محسوب می‌شوند؟

    اگه قبلا با ری‌اکت کار کرده باشین، احتملا با یه API قدیمی تر آشنا هستین که توی اون ویژگی ref یه رشته‌ست، مثل ref='textInput' و DOM به صورت refs.textInput قابل دسترسی‌ـه. البته این ویژگی توی نسخه ۱۶ ری‌اکت حذف شده و توصیه نمیشه استفاده بشه، فقط برای یادگیری هست.

    1. ری‌اکت رو مجبور می‌کنن که عناصر در حال اجرا رو دنبال کنه و این مساله یکم مشکل سازه چون باعث میشه خطاهای عجیب و غریب وقتی که ماژول ری‌اکت باندل میشه، رخ بده.

    2. قابل انعطاف نیستن. اگه یه کتابخونه خارجی یه ref رو روی فرزند قرار بده، کاربر نمی‌تونه یه ref دیگه‌ای رو روی اون اضافه کنه.

    3. با یه آنالیزگر استاتیک مثل Flow کار نمی‌کنه و در حقیقت Flow یا تایپ‌اسکریپت نمی‌تونه حدس بزنه که فریم‌ورک چه کاری روی ref انجام میده، مثل نوع داده اون(که ممکنه متفاوت باشه). refهای callbackدار بیشتر با آنالیزگرها سازگارترن.

    4. اون طور که اکثر مردم از الگوی "render callback" انتظار دارن کار نمی کنه(برای مثال <DataGrid renderRow={this.renderRow} />)

    class MyComponent extends Component {
      renderRow = (index) => {
        // This won't work. Ref will get attached to DataTable rather than MyComponent:
        return <input ref={"input-" + index} />;
    
        // This would work though! Callback refs are awesome.
        return <input ref={(input) => (this["input-" + index] = input)} />;
      };
    
      render() {
        return <DataTable data={this.props.data} renderRow={this.renderRow} />;
      }
    }
    

    فهرست

  2. Virtual DOM چیه؟

    Virtual DOM(VDOM) یه کپی داخل memory از DOM واقعی هستش. این کپی از المان‌های رابط کاربری توی حافظه رم نگهداری میشه و همواره با DOM اصلی و واقعی همگام سازی(sync) میشه. این مرحله بین تابع رندر و نمایش elementها روی صفحه رخ میده و به مجموعه اتفاقاتی که برای مدیریت این موارد انجام میشه reconciliation میگن.

    فهرست

  3. Virtual DOM چطوری کار می‌کنه؟

    Virtual DOM توی سه مرحله ساده کار ‌می‌کنه.

    1. هر زمان که داده‌های اساسی تغییر ‌می‌کنن، کل رابط کاربری توسط DOM مجازی مجددا رندر میشه.

      vdom

    2. تفاوت بین DOM قبلی و جدید محاسبه میشه.

      vdom2

    3. بعد از انجام محاسبات، DOM واقعی فقط با مواردی که واقعاً تغییر کردن به روز میشه.

      vdom3

    فهرست

  4. تفاوت بین Shadow DOM و Virtual DOM چیه؟

    shadow DOM یه تکنولوژی مرورگره که در ابتدا برای تعیین متغیر‌ها و ایزوله‌سازی css دروب کامپوننت(Web component) طراحی شده بود. virtual DOM مفهومیه که توسط کتابخونه‌ها برای مدیریت DOM توسط جاواسکریپت با استفاده از APIهای مرورگرها اجرا شده.

    فهرست

  5. React Fiber چیه؟

    Fiber موتور جدید برای عملیات reconciliation هست یا میشه گفت که پیاده‌سازی مجدد الگوریتم هسته ری‌اکت نسخه ۱۶ هست. هدف پیاده‌سازی ReactFiber برای بهبود کارکرد توی جاهایی مثل ایجاد انیمیشن، کار روی layout، کار با gestureها و قابلیت اینکه عملیات در حال اجرا رو متوقف، قطع یا مجددا فعال کنیم ساخته شده. البته می‌تونه برای اولویت‌بندی بروزسانی‌های لازم توی DOM رو هم مدیریت کنه.

    فهرست


  1. هدف اصلی React Fiber چیه؟

    هدف پیاده‌سازی ReactFiber برای بهبود کارکرد توی ناحیه‌هایی مثل انیمیشن، layout، کار با gestureها بود. میشه گفت مهم‌ترین ویژگی incremental-rendering بوده که قابلیت بخش‌بندی(chunk کردن) عملیات اجرایی و متوقف و اجرا کردن اون توی فریم‌های مختلف هست.

    فهرست

  2. کامپوننت‌های کنترل شده چی هستن؟

    کامپوننتی که عناصر ورودی رو توی فرم‌های ورودی کاربر کنترل‌می‌کنه به عنوان کامپوننت کنترل شده شناخته میشن، توی این کامپوننت‌ها هر تغییر state یه تابع نگهدارنده مرتبط باهاش رو داره.

    به عنوان مثال، اگر یه input داشته باشیم و بخواییم اسم فرد رو بگیریم و به شکل حروف بزرگ نگهداری کنیم، باید از handleChange مثل زیر استفاده کنیم:

    const [name, setName] = useState('');
    const handleChange = (event) => {
      setName(event.target.value.toUpperCase());
    }
    
    return <input value={name} onChange={handleChange} />
    

    فهرست

  3. کامپوننت‌های کنترل نشده چی هستن؟

    کامپوننت‌های کنترل نشده کامپوننت‌هایی هستن که stateهاشون رو به صورت داخلی ذخیره می کنن و ما می‌تونیم با استفاده از یک ref و از روی DOM مقدار فعلی اون input رو پیدا کنیم. این یکم شبیه HTML سنتیه.

    مثلا توی کامپوننت UserProfile زیر، ورودی name با استفاده از ref قابل دسترسیه.

    const UserProfile = () => {
      const inputRef = useRef();
    
      const handleSubmit = (event) => {
        alert("A name was submitted: " + inputRef.current.value);
        event.preventDefault();
      }
    
      
      return (
        <form onSubmit={handleSubmit}>
          <label>
            {"Name:"}
            <input type="text" ref={input} />
          </label>
          <input type="submit" value="Submit" />
        </form>
      );
    }
    

    اکثر مواقع، توصیه میشه که از کامپوننت‌های کنترل‌شده بجای این روش برای پیاده‌سازی فرم‌ها و دریافت داده استفاده کنیم.

    فهرست

  4. تفاوت‌های بین createElement و cloneElement کدوما هستن؟

    عناصر JSX به توابع React.createElement تبدیل میشن تا عناصر ری‌اکتی بسازن که برای نمایش UI استفاده میشن. درحالی که cloneElement برای کلون کردن یه عنصر و فرستادنش به عنوان prop جدید استفاده میشه.

    فهرست

  5. مفهوم lift state up یا مدیریت state در لول بالاتر رو توضیح میدی؟

    وقتی که کامپوننت‌های مختلف نیاز به یه داده خاص دارن که بین اونا مشترکه بهتره stateهای مشترک رو تا حد امکان به نزدیک‌ترین کامپوننت بالایی‌شون انتقال بدیم. این مورد به این معنیه که اگه دو کامپوننت فرزند داریم که یه state مشخص رو دارن مدیریت می‌کنن توی خودشون، اون state رو می‌بریم توی کامپوننت والد و بجای مدیریت یه state توی دوتا کامپوننت، از یه جا و توی کامپوننت والد اون رو مدیریت می‌کنیم.

    فهرست

  6. فازهای مختلف از lifecycle کامپوننت کدوما هستن؟

    چرخه حیات کامپوننت سه مرحله داره:

    1. Mounting: کامپوننت آماده اجرا روی DOM مرورگر هستش. این مرحله مقداردهی اولیه از متدهای lifecycle constructor، ‍‍getDerivedStateFromProps، ‍‍render و componentDidMount رو پوشش میده.

    2. Updating: در این مرحله، کامپوننت از دو طریق به روزرسانی میشه، ارسال prop‌های جدید و به روزرسانی state از طریق setState. این مرحله متد‌های getDerivedStateFromProps، shouldComponentUpdate، render، getSnapshotBeforeUpdate و componentDidUpdate رو پوشش میده.

    3. Unmounting: در مرحله آخر کامپوننت مورد نیاز نیست و از DOM مرورگر حذف میشه. این مرحله فقط شامل متد ‍‍componentWillUnmount میشه.

    البته بهتره اینجا این نکته رو بگیم که ری‌اکت برای به روز کردن DOM یه سری فازبندی‌هایی داره که خود اون مرحله رو توی سه تا فاز انجام میده. این پایین به این فازبندی‌ها اشاره می‌کنیم.

    1. Render کامپوننت بدون هیچ سایدافکتی رندر میشه. این فقط در مورد کامپوننت‌های خالص صدق‌می‌کنه و در این مرحله، ری‌اکت می‌تونه رندر رو متوقف، حذف یا restart کنه.

    2. Pre-commit قبل از اینکه کامپوننت تغییرات رو روی DOM‌ اعمال کنه، لحظه‌ای وجود داره که به ری‌اکت اجازه میده از DOM داخل متد getSnappshotBeforeUpdate بخونه.

    3. Commit ری‌اکت با DOM کار‌می‌کنه و lifecycle‌های آخر رو به ترتیب اجرا‌می‌کنه، ‍‍componentDidMount برای نصب، componentDidUpdate برای به روزرسانی و componentWillUnmount برای غیرفعال کردن.

    مراحل ری‌اکت ۱۶.۳ (یا نسخه تعاملی)

    فازهای 16.3+

    قبل از ورژن ۱۶.۳

    فازهای 16.2

    فهرست

  7. متدهای lifecycle کامپوننت کدوما هستن؟

    ری‌اکت ۱۶.۳ به بعد

    • getDerivedStateFromProps: درست قبل از اینکه Render اجرا بشه فراخوانی میشه و در هر بار render فراخوانی میشه.
      برای موارد نادری که نیاز داریم از state مشتق بگیریم این متد استفاده میشه. بهتره که اینو بخونید [اگه نیاز داشتین که از state مشتق بگیرین] (https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html).
    • componentDidMount: بعد از اولین رندر اجرا میشه و همه درخواست‌های AJAX، DOM یا بروزرسانی state و تنظیمات event listeners اجرا میشه.

    • shouldComponentUpdate: تعیین‌می‌کنه که کامپوننت به روز بشه یا نه. به طور پیش فرض مقدار true رو برمی‌گردونه. اگه مطمئن باشیم که کامپوننت بعد از اینکه state یا props به روزرسانی میشه نیازی به رندر شدن نداره، می‌تونیم مقدار false رو برگردونیم. اینجا جای خوبی برای بهبود عملکرده چون این امکان رو بهمون میده که اگه کامپوننت prop جدید میگیره از render مجدد جلوگیری کنیم.

    • getSnapshotBeforeUpdate: درست قبل از رندر مجدد خروجی به DOM اجرا میشه. هر مقداری که توسط این متد برگشت داده میشه به متد componentDidUpdate انتقال داده میشه. برای گرفتن اطلاعات از موقعیت اسکرول DOM مفیده.

    • componentDidUpdate: بیشتر برای به روزرسانی DOM در پاسخ به تغییرات state‌ یا Prop استفاده میشه. این متد زمانی که shouldComponentUpdate مقدار false رو برگردونه قابل استفاده ست.

    • componentWillUnmount این متد برای کنسل کردن همه درخواست‌های شبکه خروجی یا حذف همه event listener‌های مرتبط با کامپوننت استفاده میشه.

    قبل ورژن ۱۶.۳

    • componentWillMount: قبل از رندر اجرا میشه و برای پیکربندی سطح برنامه توی کامپوننت ریشه استفاده میشه.

    • componentDidMount: بعد از اولین رندر اجرا میشه و همه درخواست‌های AJAX، DOM یا بروزرسانی state و تنظیمات event listeners اجرا میشه.

    • componentWillReceiveProps: Executed when particular prop updates to trigger state transitions.

    • shouldComponentUpdate: تعیین‌می‌کنه که کامپوننت به روز بشه یا نه. به طور پیش فرض مقدار true رو برمی‌گردونه. اگه مطمئن باشیم که کامپوننت بعد از اینکه state یا props به روزرسانی میشه نیازی به رندر شدن نداره، می‌تونیم مقدار false رو برگردونیم. اینجا جای خوبی برای بهبود عملکرده چون این امکان رو بهمون میده که اگه کامپوننت prop جدید میگیره از render مجدد جلوگیری کنیم.

    • componentWillUpdate: قبل از رندر مجدد کامپوننت وقتی که تغییرات state و props توسط ‍‍‍‍shouldComponentUpdate مقدار ‍‍true رو برگردونده باشه اجرا میشه.

    • componentDidUpdate: بیشتر برای به روزرسانی DOM در پاسخ به تغییرات state‌ یا Prop استفاده میشه. این متد زمانی که shouldComponentUpdate مقدار false رو برگردونه قابل استفاده ست.

    • componentWillUnmount این متد برای کنسل کردن همه درخواست‌های شبکه خروجی یا حذف همه event listener‌های مرتبط با کامپوننت استفاده میشه.

      فهرست

  8. کامپوننت‌های Higher-Order چی هستن؟

    کامپوننت با مرتبه بالا(HOC) تابع‌ـیه که یه کامپوننت می‌گیره و یه کامپوننت جدید برمی‌گردونه. اصولا این الگوییه که از ماهیت تلفیقی ری‌اکت گرفته شده.

    ما اینا رو به عنوان کامپوننت‌های خالص می‌شناسیم چون می‌تونن هر کدوم از کامپوننت‌های فرزندشون رو که به صورت پویا ارائه شدن رو بپذیرن ولی هیچ کدوم از رفتارهای کامپوننت‌های ورودی خودشون رو تغییر نمیدن.

    const EnhancedComponent = higherOrderComponent(WrappedComponent);
    

    HOC خیلی جاها می‌تونه استفاده بشه:

    1. استفاده مجدد از کد، منطق و مفهوم bootstrap.

    2. استفاده برای Render hijacking و کنترل خروجی رندر کامپوننت.

    3. مفهوم state و دستکاری اون.

    4. دستکاری propها.

    فهرست

  9. چطوری می‌تونیم props proxy برای کامپوننت‌های HOC ایجاد کنیم؟

    می‌تونیم prop‌های انتقال داده شده به کامپوننت رو با استفاده از الگوی props proxy اضافه یا ویرایش کنیم:

    function HOC(WrappedComponent) {
      return class Test extends Component {
        render() {
          const newProps = {
            title: "New Header",
            footer: false,
            showFeatureX: false,
            showFeatureY: true,
          };
    
          return <WrappedComponent {...this.props} {...newProps} />;
        }
      };
    }
    

    فهرست

  10. context چیه؟

    Context روشی رو برای انتقال داده‌ بین کامپوننت‌ها فراهم ‌می‌کنه بدون اینکه بخوایم توی هر سطح به صورت دستی داده‌ها رو منتقل کنیم. به عنوان مثال، معتبر بودن کاربر، چند زبانگی و فایل‌های زبان، قالب UI مواردی هستن که توی خیلی از کامپوننت‌ها و به شکل عمومی لازم داریم که در دسترس باشن و می‌تونیم از context برای مدیریت‌شون استفاده کنیم.

    const { Provider, Consumer } = React.createContext(defaultValue);
    

    فهرست

  11. children prop چیه؟

    children یه prop هستش که بهمون اجازه میده کامپوننت‌ها رو به عنوان فرزند و به شکل داده به کامپوننت‌های دیگه انتقال بدیم (prop.children)، درست مثل prop‌های دیگه‌ای که استفاده می‌کنیم. درخت کامپوننت که بین تگ باز و بسته کامپوننت‌ها قرار داره به اون کامپوننت به عنوان prop children پاس داده میشه.

    یه تعداد متد برای کار بااین prop‌ها روی react API وجود داره که شامل React.Children.map، React.Children.forEach، React.Children.count، React.Children.only، React.Children.toArray میشه.
    یه مثال ساده از استفاده از children prop این پایین نوشته شده.

    const MyDiv = React.createClass({
      render: function () {
        return <div>{this.props.children}</div>;
      },
    });
    
    ReactDOM.render(
      <MyDiv>
        <span>{"Hello"}</span>
        <span>{"World"}</span>
      </MyDiv>,
      node
    );
    

    فهرست

  12. چطوری میشه تو React کامنت نوشت؟

    کامنت‌ها توی React/JSX شبیه به جاواسکریپت هستن اما کامنت‌های چند خطی توی آکولاد قرار میگیرن.

    کامنت‌های تک خطی:

    <div>
      {/* Single-line comments(In vanilla JavaScript, the single-line comments are represented by double slash(//)) */}
      {`Welcome ${user}, let's play React`}
    </div>
    

    کامنت‌های چند خطی:

    <div>
      {/* Multi-line comments for more than
       one line */}
      {`Welcome ${user}, let's play React`}
    </div>
    

    فهرست


  1. چرا توی کامپوننت‌های کلاس باید توی constructor تابع super رو با مقدار props صدا بزنیم؟

    کلاس constructor تا زمانی که متد super صدا زده نشده نمی‌تونه از this استفاده کنه. همین مورد در رابطه با کلاس‌های ES6 هم صدق می‌کنه. دلیل اصلی انتقال پارامتر‌های props به متد فراخوان super دسترسی داشتن به this.props توی constructor هستش.

    با پاس دادن props:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
    
        console.log(this.props); // prints { name: 'John', age: 42 }
      }
    }
    

    بدون پاس داده شدن props:

    class MyComponent extends React.Component {
      constructor(props) {
        super();
    
        console.log(this.props); // prints undefined
    
        // but props parameter is still available
        console.log(props); // prints { name: 'John', age: 42 }
      }
    
      render() {
        // no difference outside constructor
        console.log(this.props); // prints { name: 'John', age: 42 }
      }
    }
    

    کد بالا نشون میده که this.props فقط توی constructor متفاوت عمل می‌کنه و بیرون از constructor عملکردش عادیه، دلیلش هم اینه که توی متد سازنده کلاس، هنوز instance کامل ساخته نشده و در حال ساخته شدنه.

    فهرست


  1. reconciliation چیه؟

    وقتی state‌ یا props یه کامپوننت تغییر‌می‌کنه، ری‌اکت با مقایسه عنصر تازه return شده و نمونه render شده قبلی تصمیم میگیره که به روزرسانی DOM واقعا ضروریه یا نه. وقتی این دو مقدار با هم برابر نباشه، ری‌اکت به روزرسانی DOM رو انجام میده. به این فرایند reconciliation گفته میشه.

    فهرست

  2. چطوری با یه اسم داینامیک set state کنیم؟

    اگر برای تبدیل کد JSX از ES6 یا babel استفاده می‌کنین می‌تونید این کار رو با computed property names انجام بدین.

    handleInputChange(event) {
      this.setState({ [event.target.id]: event.target.value })
    }
    

    اینجا ما یه فیلد از Object رو به شکل متغیر داریم پر می‌کنیم، البته روی فانکشن کامپوننت‌ها و با استفاده از هوک useState هم میشه به شکل داینامیک یه object رو پر کرد و فقط لازمه یه state به شکل object داشته باشیم:

    const [myState, setMyState] = useState();
    const handleInputChange = (event) => {
      setMyState({ [event.target.id]: event.target.value });
    }
    

    فهرست

  3. یه اشتباه رایج برای مدیریت توابع eventها که باعث میشه با هر رندر توابع مجدد ساخته بشن چی هستش؟

    باید مطمئن باشیم که موقع استفاده از تابع هندلرمون به عنوان پارامتر، اون تابع صدا زده نشه. مثلا:

    // Wrong: handleClick is called instead of passed as a reference!
    return <button onClick={this.handleClick()}>{'Click Me'}</button>
    

    و به جاش تابع رو بدون پرانتز(فراخوانی) و به شکل رفرنس پاس بدیم:

    // Correct: handleClick is passed as a reference!
    return <button onClick={this.handleClick}>{'Click Me'}</button>
    

    فهرست

  4. تابع lazy که برای lazy load استفاده میشه رو می‌تونیم به صورت name export خروجی بگیریم؟

    نه، تابع React.lazy در حال حاضر فقط خروجی پیش فرض(default export) رو پشتیبانی‌می‌کنه. اگه بخوایم ماژول‌هایی رو import کنیم که به شکل پیش‌فرض exports نشدن، می‌تونیم یه ماژول واسطه تعریف کنیم که اونا رو به عنوان پیش فرض مجددا تعریف‌ می‌کنه. همچنین تضمین‌ می‌کنه که tree shaking همچنان به کار خودش ادامه میده و کامپوننت‌ موردنظر کدهای استفاده نشده رو نمی‌گیره.
    بیاین یه کامپوننتی بنویسیم که چندین کامپوننت رو به عنوان خروجی ارائه میده.

    // MoreComponents.js
    export const SomeComponent = /*... */;
    export const UnusedComponent = /*... */;
    

    و کامپوننت MoreComponents.js رو در فایل واسطه IntermediateComponent.js مجددا به عنوان خروجی تعریف کنیم.

    // IntermediateComponent.js
    export { SomeComponent as default } from "./MoreComponents.js";
    

    حالا می‌تونیم ماژول خودمون رو با استفاده از تابع lazy به شکل زیر import کنیم.

    import React, { lazy } from "react";
    const SomeComponent = lazy(() => import("./IntermediateComponent.js"));
    

    فهرست

  5. چرا ری‌اکت از className بجای class استفاده می‌کنه؟

    class یه کلمه کلیدی توی جاواسکریپت‌ـه و فایل با پسوند JSX در حقیقت همون فایل جاواسکریپت‌ـه. دلیل اصلی استفاده ری‌اکت از className به جای class همینه و یه مقدار رشته‌ای رو به عنوان پارامتر className پاس میدیم. مثل کد زیر:

    render() {
      return <span className='menu navigation-menu'>Menu</span>
    }
    

    فهرست

  6. fragmentها چی هستن؟

    یه الگوی مشخص توی ری‌اکت وجود داره که برای کامپوننت‌هایی استفاده میشه که چندین عنصر یا کامپوننت رو برمیگردونن. _Fragment_‌ها این امکان رو فراهم می‌کنن که بتونیم لیستی از فرزندان رو بدون اضافه کردن نود‌های اضافی به DOM گروه بندی کنیم.

    render() {
      return (
        <React.Fragment>
          <ChildA />
          <ChildB />
          <ChildC />
        </React.Fragment>
      )
    }
    

    همچنین یه حالت مختصرتر هم وجود داره که به شکل زیر می‌تونیم fragment بسازیم:

    render() {
      return (
        <>
          <ChildA />
          <ChildB />
          <ChildC />
        </>
      )
    }
    

    فهرست

  7. چرا fragmentها از تگ‌های div بهترن؟

    البته می‌دونیم که نه فقط div بلکه از بقیه تگ‌های html هم میشه بجای fragment استفاده کرد ولی به دلایل زیر بهتره از fragment استفاده بشه:

    1. Fragment‌ها یه کم سریعترن و با ایجاد نکردن DOM node اضافی حافظه کمتری استفاده می‌کنن. این فقط روی nodeهای بزرگ و درخت‌های بزرگ و عمیق مزیت داره.

    2. بعضی از مکانیزم‌های CSS مثل Flexbox و CSS Grid روابط والد و فرزندی خاصی دارند و اضافه کردن div در وسط، حفظ طرح مورد نظرمون را دشوار‌می‌کنه.

    3. DOM Inspector بهم ریختگی کمتری داره و میشه راحت‌تر کدهای برنامه رو دیباگ کرد.

    فهرست

  8. توی ری‌اکت portal‌ها چیکار می‌کنن؟

    Portal روشی توصیه شده برای رندر کردن کامپوننت فرزند به شکل DOM و خارج از سلسله مراتب DOM کامپوننت والد هستش.

    ReactDOM.createPortal(child, container);
    

    اولین آرگومان یه فرزند قابل رندر شدن هستش، مثل عنصر، رشته، یا fragment. آرگومان دوم عنصر DOM هستش.

    فهرست

  9. کامپوننت stateless چیه؟

    اگه رفتار یه کامپوننت مستقل از state اون کامپوننت باشه بهش کامپوننت stateless گفته میشه. می‌تونیم از یه تابع یا یه کلاس برای ساخت کامپوننت‌های stateless استفاده کنیم،

    فهرست

  10. کامپوننت stateful چیه؟

    اگه رفتار یه کامپوننتی به state اون کامپوننت وابسته باشه، به عنوان کامپوننت statefull شناخته میشه.

    const App = () => {
      const [count, setCount] = useState(0);
    
      return (
        //...
      );
    }
    

    قبل از نسخه 16.8 ری‌اکت:
    قبل از اینکه هوک‌ها این امکان رو بهمون بدن که بتونیم از state و ویژگی‌های دیگه ری‌اکت استفاده کنیم بدون نوشتن کلاس‌ کامپوننت‌ها استفاده کنیم، نمی‌تونستیم فانکشن کامپوننت رو statefull کنیم و مجبور بودیم برای کامپوننت ساده فوق یه همچین کلاسی بنویسیم:

    class App extends Component {
        constructor(props) {
            super(props);
            this.state = { count: 0 };
        }
    
        render() {
          // ...
        }
    }
    

    فهرست

  11. چطوری prop‌های کامپوننت رو اعتبارسنجی کنیم؟

    وقتی برنامه توی حالت development یا در حال توسعه هست، ری‌اکت به شکل خودکار تمام propهایی که ما توی کامپوننت استفاده کردیم رو چک می‌کنه تا مطمئن بشه همه‌شون نوع درستی دارن. اگه هر کدوم از propها type درستی نداشته باشن توی کنسول بهمون یه warning نشون میده، البته توی حالت production این حالت غیر فعاله.
    prop‌های اجباری با پراپرتی isRequired مشخص میشن، همچنین یه‌سری انواع prop از پیش تعریف شده وجود دارن که می‌تونیم ازشون استفاده کنیم:

    1. PropTypes.number

    2. PropTypes.string

    3. PropTypes.array

    4. PropTypes.object

    5. PropTypes.func

    6. PropTypes.node

    7. PropTypes.element

    8. PropTypes.bool

    9. PropTypes.symbol

    10. PropTypes.any


    PropTypeها رو برای یه کامپوننت تستی به اسم User اینطوری میشه تعریف کرد:

    import React from "react";
    import PropTypes from "prop-types";
    
    const User = (props) => {
      return (
        <>
          <h1>{`Welcome, ${props.name}`}</h1>
          <h2>{`Age, ${props.age}`}</h2>
        </>
      );
    }
    
    User.propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number.isRequired,
    };
    

    نکته: در ورژن 15.5 ری‌اکت propTypeها از ‍React.PropType به کتابخونه جدید prop-types انتقال پیدا کردن.

    فهرست

  12. مزایای React چیه؟

    1. افزایش عملکرد برنامه با Virtual DOM.

    2. خوندن و نوشتن راحتتر کد‌ها با JSX.

    3. امکان رندر شدن در هر دو سمت کاربر و سرور (SSR).

    4. ادغام راحت با فریم ورک‌ها (Angular, Backbone).

    5. امکان نوشتن تست‌های واحد یا ادغام شده از طریق ابزارهایی مثل Jest.

    فهرست


  1. محدودیت‌های React چیه؟

    1. ری‌اکت یک کتابخونه برای ساخت لایه view هستش نه یک فریم‌ورک کامل.

    2. وجود یک منحنی یادگیری(سختی یادگیری یا همون learning curve) برای کسایی که به تازگی می خوان برنامه نویسی وب رو یاد بگیرن.

    3. یکپارچه‌سازی ری‌اکت در فریم‌ورک‌های مبتنی بر MVC به یه کانفیگ اضافه‌ای نیاز داره.

    4. پیچیدگی کد با inline templating و JSX افزایش پیدا‌می‌کنه.

    5. خیلی کامپوننت‌های کوچیک یا boilerplateهای کوچیک براش ساخته شدن و ممکنه کمی گیج کننده باشه.

    فهرست

  2. error boundaryها توی ری‌اکت نسخه 16 چیکار می‌کنن؟

    Error boundaryها یا به اصطلاح تحت الفظی مرزهای خطا کامپوننت‌هایی هستن که خطاهای جاواسکریپت رو هرجایی توی درخت فرزنداش رخ داده باشن catch می‌کنن و خطای موردنظر رو log می‌کنن و علاوه براین می‌تونن یه UI به اصطلاح fallback رو بجای کامپوننت crash شده نشون بدن.

    توی یه کلاس کامپوننت با گذاشتن متد componentDidCatch(error, info) یا static getDerivedStateFromError می‌تونیم یه boundary برای زمانی که خطایی رخ میده درست کنیم. مثل:

    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = { hasError: false };
      }
    
      componentDidCatch(error, info) {
        // You can also log the error to an error reporting service
        logErrorToMyService(error, info);
      }
    
      static getDerivedStateFromError(error) {
        // Update state so the next render will show the fallback UI.
        return { hasError: true };
      }
    
      render() {
        if (this.state.hasError) {
          // You can render any custom fallback UI
          return <h1>{"Something went wrong."}</h1>;
        }
        return this.props.children;
      }
    }
    

    بعدشم میشه ازش مثل یه کامپوننت عادی استفاده کرد:

    <ErrorBoundary>
      <MyWidget />
    </ErrorBoundary>
    

    نکته: از این قابلیت با استفاده از کامپوننت‌های functional نمیشه استفاده کرد و در حقیقت احتمالا نیازی هم بهش ندارین، چون اکثر مواقع برای کل برنامه یه error boundary تعریف می‌کنیم که می‌تونه try..catch باشه.

    فهرست

  3. چطوری از error boundaryها توی نسخه 15 ری‌اکت استفاده کنیم؟

    ری‌اکت توی نسخه 15 با استفاده از متد unstabled_handleError error boundaryها رو مدیریت کرده.
    این متد توی نسخه 16 به ‍‍componentDidCatch تغییر کرده.

    فهرست

  4. روش‌های پیشنهادی برای type checking چیه؟

    به طور معمول به دو روش میشه نوع prop ورودی در برنامه‌های ری‌اکتی رو چک کرد. روش اول استفاده از کتابخانه prop-types و اعتبارسنجی ورودی‌های کامپوننت‌‌ـه و روش دوم که برای برنامه‌هایی با کد‌های بیشتر توصیه میشه، استفاده از _static type checker_‌هایی مثل flow یا typeScript هست که چک کردن نوع داده رو در زمان توسعه و کامپایل انجام میده ویژگی‌های مثل auto-completion ‌رو ارائه میده.

    فهرست

  5. کاربرد پکیج react-dom چیه؟

    پکیج react-dom متدهای DOM-specific یا مخصوص DOM رو ارائه میده که می‌تونه توی سطوح بالای برنامه شما استفاده بشه.
    اکثر کامپوننت‌ها نیازی به استفاده از این ماژول‌ها ندارن. تعدادی از متد‌های این پکیج این‌ها هستن:

    1. متد render

    2. متد hydrate

    3. متد unmountComponentAtNode

    4. متد findDOMNode

    5. متد createPortal

    فهرست

  6. کاربرد متد render از پکیج react-dom چیه؟

    این متد برای رندرکردن کامپوننت پاس داده شده، توی یه المنت DOM که به عنوان container پاس داده شده، استفاده میشه و یه رفرنس به کامپوننت برمی‌گردونه. اگه کامپوننت ری‌اکت قبلا توی container مورد نظر رندر شده باشه با یه update فقط DOMهایی که نیازمند به روز شدن باشن رو ری-رندر می‌کنه.

    ReactDOM.render(element, container[, callback])
    

    اگه پارامتر سوم که یه callback هست پاس داده بشه، هر موقع که رندر یا به‌روزرسانی انجام بشه اون تابع هم اجرا میشه.

    فهرست

  7. ReactDOMServer چیه؟

    ReactDOMServer این امکان رو بهمون میده که کامپوننت‌ها رو به صورت استاتیک رندر کنیم (معمولا روی node server استفاده میشه). ReactDOMServer عمدتا برای پیاده سازی سمت سرور استفاده میشه (SSR).

    1. متد renderToString

    2. متد renderToStaticMarkup

    برای مثال ممکنه یه سرور روی node بسازین که ممکنه Express، Hapi یا Koa باشه و متد renderToString رو برای تبدیل کردن کامپوننت root به html اجرا کنید و نتیجه بدست اومده رو به عنوان response به کلاینت پاس بدین.

    // using Express
    import { renderToString } from "react-dom/server";
    import MyPage from "./MyPage";
    
    app.get("/", (req, res) => {
      res.write(
        "<!DOCTYPE html><html><head><title>My Page</title></head><body>"
      );
      res.write('<div id="content">');
      res.write(renderToString(<MyPage />));
      res.write("</div></body></html>");
      res.end();
    });
    

    فهرست

  8. چطوری از InnerHtml توی ری‌اکت استفاده کنیم؟

    ویژگی dangerouslySetInnerHTML جایگزین ری‌اکت واسه استفاده از innerHTML توی DOM مرورگره و کارکردش درست مثل innerHTML هستش، استفاده از این ویژگی به خاطر حملات cross-site-scripting(XSS) ریسک بالایی داره.
    برای این‌کار باید یه آبجکت innerHTML به عنوان key و یه متن html به عنوان value به این prop بفرستیم(یا شاید همون پاس بدیم).

    توی مثال پایینی کامپوننت از ویژگی dangerouslySetInnerHTML برای قرار دادن HTML استفاده کرده.

    function createMarkup() {
      return { __html: "First &middot; Second" };
    }
    
    function MyComponent() {
      return <div dangerouslySetInnerHTML={createMarkup()} />;
    }
    

    فهرست

  9. چطوری توی ری‌اکت استایل‌دهی می‌کنیم؟

    attribute پیش‌فرض مورد استفاده برای استایل‌دهی style هستش که یه object جاواسکریپت رو به عنوان مقدار ورودی دریافت می‌کنه. همه propertyهای اون بجای css عادی camelCase هستن. این روش با استایل‌دهی عادی توی جاواسکریپت یه کم متفاوت، بهینه‌تر و امن‌تره، چون جلوی حفره‌های امنیتی مثل XSS رو میگیره.

    const divStyle = {
      color: "blue",
      backgroundImage: "url(" + imgUrl + ")",
    };
    
    function HelloWorldComponent() {
      return <div style={divStyle}>Hello World!</div>;
    }
    

    فهرست

  10. تفاوت eventهای ری‌اکت چیه؟

    مدیریت رویداد‌ها روی اِلمان‌های ری‌اکت یه سری تفاوت‌های کلی با نحوه مدیریت اونا روی js داره:

    1. event handler‌های ری‌اکت یه جای حروف کوچیک به صورت حروف بزرگ نام‌گذاری میشن.

    2. با JSX ما یه تابع رو به جای رشته به عنوان event handler پاس میدیم.

    فهرست


  1. اگه توی constructor بیاییم و setState کنیم چی میشه؟

    وقتی از setState استفاده می‌کنیم، جدا از اینکه به یه آبجکت استیتی اختصاص داده میشه ری‌اکت اون کامپوننت و همه فرزندای اون کامپوننت رو دوباره رندر می‌کنه. ممکنه این ارور رو بگیرین: شما فقط می تونید کامپوننت mount شده یا در حال mount رو به روز رسانی کنید. پس باید بجای setState از this.state برای مقداردهی state توی constructor استفاده کنیم.
    توی فانکشن کامپوننت‌ها هم اگه داخل بدنه تابع یه setState کنیم، کامپوننت توی حلقه رندر بی‌نهایت می‌افته و خطا می‌گیریم.

    فهرست

  2. تاثیر استفاده از ایندکس به عنوان key چیه؟

    key‌ها باید پایدار، قابل پیش بینی و منحصر به فرد باشن تا ری‌اکت بتونه اِلمان‌ها رو رهگیری کنه.
    تو کد زیر key هر عنصر براساس ترتیبی که توی لیست داره مقدار قرار می گیره و به داده‌هایی که میگیرن ربطی نداره. این کار بهینه سازی‌هایی که می‌تونه توسط ری‌اکت انجام بشه رو محدود‌ می‌کنه.

    todos.map((todo, index) => <Todo {...todo} key={index} />);
    

    اگه از داده‌های همون element به عنوان کلید بخوایم استفاده کنیم، مثلا todo.id. چونکه همه ویژگی‌هایی که یه کلید باید داشته باشه رو داره، هم استیبله و هم منحصر به فرد، توی این حالت ری‌اکت می‌تونه بدون اینکه لازم باشه دوباره همه اِلمنت‌ها رو ارزیابی کنه رندر رو انجام بده.

    todos.map((todo) => <Todo {...todo} key={todo.id} />);
    

    فهرست

  3. نظرت راجع به استفاده از setState توی متد componentWillMount چیه؟

    توصیه میشه که از مقدار دهی اولیه غیرهمزمان(async) در متد componentWillMount استفاده نشه. componentWillMount درست قبل از mount شدن اجرا میشه و اون لحظه قبل از فراخوانی متد render هست، پس setState کردن توی این متد باعث re-render شدن نمیشه. باید از ایجاد هر ساید افکتی توی این متد خودداری کنیم و دقت کنیم که اگه مقدار دهی اولیه غیر همزمان‌ای داریم این کار رو توی متد componentDidMount انجام بدیم نه در متد componentWillMount.

    componentDidMount() {
      axios.get(`api/todos`)
       .then((result) => {
          this.setState({
            messages: [...result.data]
          })
        })
    }
    

    معادل کد زیر با هوک:

    useEffect(() => {
      axios.get(`api/todos`)
       .then((result) => {
          setMessages([...result.data])
        })
    }, []);
    

    فهرست

  4. اگه از prop توی مقداردهی اولیه state استفاده کنیم چی میشه؟

    اگه prop‌های یه کامپوننت بدون اینکه اون کامپوننت رفرش بشه تغییر کنه، مقدار جدید اون prop نمایش داده نمیشه چون state جاری اون کامپوننت رو به روز رسانی نمی‌کنه، مقدار دهی اولیه state از prop‌ها فقط زمانی که کامپوننت برای بار اول ساخته شده اجرا میشه.
    کامپوننت زیر مقدار به روزرسانی شده رو نشون نمیده:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          records: [],
          inputValue: this.props.inputValue,
        };
      }
    
      render() {
        return <div>{this.state.inputValue}</div>;
      }
    }
    

    و نکته جالبش اینه که استفاده از prop‌ها توی متد render مقدار رو به روز رسانی‌می‌کنه:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          record: [],
        };
      }
    
      render() {
        return <div>{this.props.inputValue}</div>;
      }
    }
    

    توی فانکشن کامپوننت‌ها هم دقیقا به همین شکل هست، مقدار اولیه useState اگه از prop ورودی کامپوننت باشه، با تغییر دادن prop مقدار اون state عوض نمیشه، دلیلش هم اینه که هوک useState فقط توی اولین رندر اجرا میشه و بعدش دیگه باید با استفاده از متد setterاش مقدار اون state رو عوض کنیم.

    فهرست

  5. چطوری کامپوننت رو با بررسی یه شرط رندر می‌کنیم؟

    بعضی وقتا ما می خوایم کامپوننت‌های مختلفی رو بسته به بعضی state‌ها رندر کنیم. JSX مقدار false یا undefined رو رندر نمیکنه، بنابراین ما می‌تونیم از short-circuiting شرطی برای رندر کردن بخش مشخصی از کامپوننت‌مون استفاده کنیم در صورتی که اون شرط مقدار true رو برگردونده باشه.

    const MyComponent = ({ name, address }) => (
      <div>
        <h2>{name}</h2>
        {address && <p>{address}</p>}
      </div>
    );
    

    اگه به یه شرط if-else نیاز دارین، میتونیم از عبارت شرطی سه‌گانه(ternary operator) استفاده کنیم:

    const MyComponent = ({ name, address }) => (
      <div>
        <h2>{name}</h2>
        {address ? <p>{address}</p>: <p>{"Address is not available"}</p>}
      </div>
    );
    

    فهرست

  6. چرا وقتی propها رو روی یه DOM Elemnt می‌آییم spread می‌کنیم باید مراقب باشیم؟

    وقتی ما prop هارو spread می‌کنیم این کارو با ریسک اضافه کردن اتریبیوت‌های HTML انجام میدیم که این کار خوبی نیست، به جای این کار می‌تونیم از...rest استفاده کنیم که فقط prop‌های مورد نیاز رو اضافه‌می‌کنه.

    const ComponentA = () => (
      <ComponentB isDisplay={true} className={"componentStyle"} />
    );
    
    const ComponentB = ({ isDisplay,...domProps }) => (
      <div {...domProps}>{"ComponentB"}</div>
    );
    

    فهرست

  7. چطوری از decoratorها توی ری‌اکت استفاده کنیم؟

    می‌تونیم کلاس کامپوننت ها رو decorate کنیم، که درست مثل پاس دادن کامپوننت‌ها به تابع هستش. Decorator‌ها روش قابل خواندن و انعطاف پذیرتری برای تغییر فانکشنالیتی کامپوننت‌ها هستن.

    @setTitle("Profile")
    class Profile extends React.Component {
      //....
    }
    
    /*
      title is a string that will be set as a document title
      WrappedComponent is what our decorator will receive when
      put directly above a component class as seen in the example above
    */
    const setTitle = (title) => (WrappedComponent) => {
      return class extends React.Component {
        componentDidMount() {
          document.title = title;
        }
    
        render() {
          return <WrappedComponent {...this.props} />;
        }
      };
    };
    

    نکته: Decoratorها ویژگی‌هایی هستن که در حال حاضر به ES7 اضافه نشدن، ولی توی پیشنهاد stage 2 هستن.

    فهرست

  8. چطوری یه کامپوننت رو memoize می‌کنیم؟

    در حال حاضر کتابخانه‌هایی وجود داره که با هدف memoize کردن ایجاد شدن و می‌تونن توی کامپوننت‌های تابع استفاده بشن، به عنوان مثال کتابخونه moize می‌تونه یه کامپوننت رو توی بقیه کامپوننت‌ها memoize کنه.

    import moize from "moize";
    import Component from "./components/Component"; // this module exports a non-memoized component
    
    const MemoizedFoo = moize.react(Component);
    
    const Consumer = () => {
      <div>
        {"I will memoize the following entry:"}
        <MemoizedFoo />
      </div>;
    };
    

    به روز رسانی: توی ورژن 16.6.0 ری‌اکت ،React.memo رو داریم که کارش اینه که یه کامپوننت با الویت بالاتر فراهم‌می‌کنه که کامپوننت رو تا زمانی که prop‌ها تغییر کنن، memoize می‌کنه. برای استفاده ازش کافیه زمان ساخت کامپوننت از React.memo استفاده کنیم.

    const MemoComponent = React.memo(function MemoComponent(props) {
      /* render using props */
    });
    // OR
    export default React.memo(MyFunctionComponent);
    

    فهرست

  9. چطوری باید Server-Side Rendering یا SSR رو توی ری‌اکت پیاده کنیم؟

    ری‌اکت در حال حاضر به رندر سمت نود سرور مجهزه، یه ورژن خاصی از DOM رندر در دسترسه که دقیقا از همون الگوی سمت کاربر پیروی می‌کنه.

    import ReactDOMServer from "react-dom/server";
    import App from "./App";
    
    ReactDOMServer.renderToString(<App />);
    

    خروجی این روش یه HTML معمولی به صورت یه رشته‌ست که داخل body صفحه به عنوان response سرور قرار می‌گیره.
    در سمت کاربر، ری‌اکت محتوای از قبل رندر شده رو تشخیص میده و به صورت فرآیند همگام‌سازی با اونا رو انجام میده(rehydration).

    فهرست

  10. چطوری حالت production رو برای ری‌اکت فعال کنیم؟

    میشه از پلاگین DefinePlugin که روی وب‌پک قابل استفاده هست استفاده کرد و مقدار NODE_ENV رو روی production‌ستکرد، با اینکار خطاهای اضافی یا اعتبارسنجی propTypeها روی پروداکشن غیرفعال میشه و جدای این موارد، کدهای نوشته شده بهینه‌سازی میشن و مثلا کدهای بلااستفاده حذف میشن، کم حجم‌سازی انجام میشه و درنتیجه سرعت بهتری رو می‌توته به برنامه بده چون سایز bundle ایجاد شده کوچیکتر خواهد بود.

    فهرست

  11. CRA چیه و چه مزایایی داره؟

    ابزار CLI(محیط کدهای دستوری) create-react-app این امکان رو بهمون میده که برنامه‌های ری‌اکت رو سریع و بدون مراحل پیکربندی بسازیم و اجرا کنیم.

    مثلا، بیاین برنامه Todo رو با استفاده از CRA بسازیم:

    # Installation
    $ npm install -g create-react-app
    
    # Create new project
    $ create-react-app todo-app
    $ cd todo-app
    
    # Build, test and run
    $ npm run build
    $ npm run test
    $ npm start
    
    این شامل همه اون چیزیه که ما واسه ساختن یه برنامه ری‌اکت لازم داریم:
    1. React، JSX، ES6 و روند پشتیبانی syntax.

    2. موارد اضافی زبان شامل ES6 و عملگر object spread و اینا.

    3. Autoprefixed CSS، بنابراین نیازی به -webkit- یا پیشوند‌های دیگه‌ای نداریم.

    4. یه اجرا کننده تست تعاملی با پشتیبانی داخلی برای coveraage reporting.

    5. یه سرور live development که اشتباهات معمول رو بهمون هشدار میده.

    6. یه اسکریپت بیلد برای پک و باندل کردن css، js و تصاویر برای production همراه با hash‌ها و sourcemap ها.

    فهرست

  12. ترتیب اجرا شدن متد‌های life cycle چطوریه؟

    وقتی یه نمونه‌ای از کامپوننت ساخته میشه و داخل DOM اضافه میشه، متد‌های lifecycle به ترتیب زیر صدا زده میشن.

    1. متد constructor

    2. متد static getDerivedStateFromProps

    3. متد render

    4. متد componentDidMount

    فهرست

  13. کدوم متد‌های life cycle توی نسخه 16 ری‌اکت منسوخ شدن؟

    متد‌های lifecycle روش‌های ناامن کدنویسی هستن و با رندر async مشکل بیشتری پیدا می‌کنن.

    1. متد componentWillMount

    2. متد componentWillReceiveProps

    3. متد componentWillUpdate

    تو ورژن 16.3 ری‌اکت این متدها با پیشوند UNSAFE_ متمایز شدن و تو نسخه 17 ری‌اکت حذف شد.

    فهرست

  14. کاربرد متد getDerivedStateFromProps چیه؟

    بعد از اینکه یه کامپوننت بلافاصله بدون خطا و مثل قبل rerender شد، متد استاتیک getDerivedStateFromProps صدا زده میشه.
    این متد یا state آپدیت شده رو به صورت یه آبجکت برمی گردونه یا null رو برمی گردونه که معنیش اینه prop‌های جدید به آپدیت شدن state نیازی ندارن.

    class MyComponent extends React.Component {
      static getDerivedStateFromProps(props, state) {
        //...
      }
    }
    

    متد componentDidUpdate تمام مواردی که توی متد componentWillReceiveProps هست رو پوشش میده.

    فهرست

  15. کاربرد متد getSnapshotBeforeUpdate چیه؟

    متد جدید getSnapshotBeforeUpdate بعد از آپدیت‌های DOM صدا زده میشه.
    مقدار برگشتی این متد به عنوان پارامتر سوم به متد componentDidUpdate پاس داده میشه.

    class MyComponent extends React.Component {
      getSnapshotBeforeUpdate(prevProps, prevState) {
        //...
      }
    }
    

    متد componentDidUpdate تمام مواردی که توی متد componentWillUpdate استفاده میشه رو پوشش میده.

    فهرست

  16. آیا هوک‌ها جای render props و HOC رو می‌گیرن؟

    هوک‌ها می‌تونن بسیاری از نیازهای ما رو موقع تولید کامپوننت‌های ری‌اکتی حل کنن.
    کامپوننت‌های با اولویت بالاتر و render prop‌ها هر دوشون فقط یه child رو رندر می‌کنن ولی هوک‌ها روش راحت تری رو ارائه میدن که از تودرتو بودن درخت کامپوننت‌ها جلوگیری می‌کنه.

    فهرست

  17. روش توصیه شده برای نام‌گذاری کامپوننت‌ها چیه؟

    برای نام گذاری کامپوننت‌ها توصیه میشه که از نام‌گذاری هنگام export گرفتن به جای displayName استفاده کنیم. استفاده از displayName برای نام گذاری کامپوننت:

    export default React.createClass({
      displayName: "TodoApp",
      //...
    });
    

    روش توصیه شده:

    const TodoApp = () => ();
    
    export default TodoApp;
    

    فهرست

  18. روش توصیه شده برای ترتیب متدها در کلاس کامپوننت‌ها چیه؟

    ترتیب توصیه شده متد‌ها از mounting تا render stage:

    1. متد‌های static

    2. متد constructor

    3. متد getChildContext

    4. متد componentWillMount

    5. متد componentDidMount

    6. متد componentWillReceiveProps

    7. متد shouldComponentUpdate

    8. متد componentWillUpdate

    9. متد componentDidUpdate

    10. متد componentWillUnmount

    11. event handlerها مثل onClickSubmit یا onChangeDescription

    12. متد‌های دریافت کننده برای رندر مثل getSelectReason یا getFooterContent

    13. متد‌های رندر اختیاری مثل renderNavigation یا renderProfilePicture

    14. متد render

    فهرست

  19. کامپوننت تعویض کننده یا switching چیه؟

    یه کامپوننت switcher کامپوننتی‌ـه که یکی از چندتا کامپوننت موردنظر رو رندر می‌کنه. لازمه که برای تصمیم گیری بین کامپوننت‌ها از object جاواسکریپتی استفاده کنیم.

    برای مثال، کدپایین با بررسی prop موردنظر page بین صفحات مختلف سويیچ می‌کنه:

    import HomePage from "./HomePage";
    import AboutPage from "./AboutPage";
    import ServicesPage from "./ServicesPage";
    import ContactPage from "./ContactPage";
    
    const PAGES = {
      home: HomePage,
      about: AboutPage,
      services: ServicesPage,
      contact: ContactPage,
    };
    
    const Page = (props) => {
      const Handler = PAGES[props.page] || ContactPage;
    
      return <Handler {...props} />;
    };
    
    // The keys of the PAGES object can be used in the prop types to catch dev-time errors.
    Page.propTypes = {
      page: PropTypes.oneOf(Object.keys(PAGES)).isRequired,
    };
    

    فهرست

  20. چرا نیاز میشه به تابع setState یه فانکشن callback پاس بدیم؟

    دلیلش اینه که setState یه عملیات async یا ناهمزمانه.
    state‌ها در ری‌اکت به دلایل عملکردی تغییر می‌کنن، بنابراین یه state ممکنه بلافاصله بعد از اینکه ‍setState صدا زده شد تغییر نکنه.
    یعنی اینکه وقتی setState رو صدا می زنیم نباید به state جاری اعتماد کنیم چون نمی‌تونیم مطمئن باشیم که اون state چی می‌تونه باشه.
    راه حلش اینه که یه تابع رو با state قبلی به عنوان یه آرگومان به setState پاس بدیم.

    بیاین فرض کنیم مقدار اولیه count صفر هستش. بعد از سه عملیات پشت هم، مقدار count فقط یکی افزایش پیدا می‌کنه.

    const [count, setCount] = useState(0);
    
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
    // count === 1, not 3
    

    اگه ما یه تابع به setState پاس بدیم، مقدار count به درستی افزایش پیدا می‌کنه.

    this.setState((prevState, props) => ({
      count: prevState.count + props.increment,
    }));
    // this.state.count === 3 as expected
    

    فهرست

  21. حالت strict توی ری‌اکت چیکار می‌کنه؟

    React.StrictMode یه کامپوننت مفید برای هایلایت کردن مشکلات احتمالی توی برنامه ست.
    <StrictMode> درست مثل ‍‍<Fragment> هیچ المان DOM اضافه‌ای رو رندر نمی‌کنه، بلکه warning‌ها و additional checks رو برای فرزندان اون کامپوننت فعال‌می‌کنه.
    این کار فقط در حالت development فعال میشه.

    import React from "react";
    
    function ExampleApplication() {
      return (
        <div>
          <Header />
          <React.StrictMode>
            <div>
              <ComponentOne />
              <ComponentTwo />
            </div>
          </React.StrictMode>
          <Footer />
        </div>
      );
    }
    

    توی مثال بالا، strict mode فقط روی دو کامپوننت <ComponentOne> و <ComponentTwo> اعمال میشه.

    فهرست

  22. Mixin‌های ری‌اکت چی هستن؟

    _Mixin_‌ها روشی برای جدا کردن کامپوننت‌هایی با عملکرد مشترک بودن. با توسعه یافتن ری‌اکت دیگه Mixin‌ها نباید استفاده بشن و می‌تونن با کامپوننت‌های با اولویت بالا(HOC) یا _decorator_‌ها جایگزین بشن.

    یکی از بیشترین کاربرد‌های mixin‌ها PureRenderMixin بود. ممکنه تو بعضی از کامپوننت‌ها برای جلوگیری از re-render‌های غیر ضروری وقتی prop‌ها و state با مقادیر قبلی شون برابر هستن از این mixin‌ها استفاده کنیم:

    const PureRenderMixin = require("react-addons-pure-render-mixin");
    
    const Button = React.createClass({
      mixins: [PureRenderMixin],
      //...
    });
    

    نکته مهم: mixinهای ری‌اکت منقضی شدن و دیگه کاربردی ندارن، این سوال فقط برای افزایش آگاهی توی کتاب باقی می‌مونه.

    فهرست

  23. چرا isMounted آنتی پترن هست و روش بهتر انجامش چیه؟

    کاربرد اصلی متد isMounted برای جلوگیری از فراخوانی setState بعد از unmount شدن کامپوننت هستش چونکه باعث ایجاد یه خطا میشه.
    خطاش یه چیزی مثل اینه:

    Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
    

    توی کلاس کامپوننت‌ها هم این شکلی بعضا جلوشو می‌گرفتن:

    if (this.isMounted()) {
      this.setState({...})
    }
    

    دلیل اینکه این روش توصیه نمیشه اینه که خطایی رو که ری‌اکت بهمون میداد رو داره دور میزنه و حلش نمی‌کنه. بهتره setState رو جایی انجام بدیم که توی مواقعی که کامپوننت‌ mount نیست اجرا نشه.

    البته توی نسخه‌های جدید ری‌اکت این کار رو خیلی ساده‌تر میشه انجام داد و فقط کافیه یه هوکی بنویسیم که یه ref رو مقداردهی می‌کنه و بعد با بررسی اون ref میشه فهمید که کامپوننت mount شده یا نه، مثلا:

    export const useIsMounted = () => {
      const componentIsMounted = useRef(true);
      useEffect(
        () => () => {
          componentIsMounted.current = false;
        },
        []
      );
      return componentIsMounted;
    };
    

    یا حتی یه پکیجی ساخته شده به اسم ismounted که می‌تونه بهمون کمک کنه که متوجه بشیم کامپوننت mount شده یا نه. ولی حواسمون باشه که ازش درست استفاده کنیم.

    فهرست

  24. پشتیبانی ری‌اکت از pointer eventها چطوریه؟

    _pointer Event_‌ها یه روش واحدی رو برای هندل کردن همه ی ایونت‌های ورودی ارائه میدن.
    در زمان‌های قدیم ما از موس استفاده میکردیم و برای هندل کردن ایونت‌های مربوط به اون از event listener‌ها استفاده میکردیم ولی امروزه دستگاه‌های زیادی داریم که با داشتن موس ارتباطی ندارن، مثل قلم‌ها یا گوشی‌های صفحه لمسی.
    باید یادمون باشه که این ایونت‌ها فقط تو مرورگر‌هایی کار می‌کنن که مشخصه Pointer Events رو پشتیبانی می‌کنن.

    ایونت‌های زیر در React DOM در دسترس هستن:

    1. onPointerDown

    2. onPointerMove

    3. onPointerUp

    4. onPointerCancel

    5. onGotPointerCapture

    6. onLostPointerCapture

    7. onPointerEnter

    8. onPointerLeave

    9. onPointerOver

    10. onPointerOut

    فهرست

  25. چرا باید اسم کامپوننت با حرف بزرگ شروع بشه؟

    اگه ما با استفاده از JSX کامپوننتمون رو رندر می‌کنیم، اسم کامپوننت باید با حرف بزرگ شروع بشه در غیر این صورت ری‌اکت خطای تگ غیر قابل تشخیص رو میده.
    این قرارداد به خاطر اینه که فقط عناصر HTML و تگ‌های svg می تونن با حرف کوچیک شروع بشن.

    class SomeComponent extends Component {
      // Code goes here
    }
    
    می‌تونیم کلاس کامپوننت‌هایی که با حرف کوچیک شروع میشن رو هم تعریف کنیم ولی وقتی داریم ایمپورت می‌کنیم باید شامل حروف بزرگ هم باشن:
    class myComponent extends Component {
      render() {
        return <div />;
      }
    }
    
    export default myComponent;
    

    وقتی داریم تو یه فایل دیگه‌ای ایمپورت می‌کنیم باید با حرف بزرگ شروع بشه:

    import MyComponent from "./MyComponent";
    

    فهرست

  26. آیا propهای custom توی ری‌اکت پشتیبانی میشن؟

    بله. اون قدیما ری‌اکت DOM attribute‌های ناشناخته رو نادیده می‌گرفت، اگه JSX رو با یه ویژگی‌ای نوشته بودیم که ری‌اکت تشخیص نمی‌داد، اونو نادیده می‌گرفت. به عنوان مثال:

    <div mycustomattribute="something" />
    

    در ری‌اکت ورژن 15 یه div خالی توی DOM رندر می‌کنیم:

    <div />
    

    در ری‌اکت ورژن 16 هر attribute ناشناخته‌ای توی DOM از بین میره:

    <div mycustomattribute="something" />
    

    این برای attribute‌های غیر استاندارد مرورگر‌های خاص، DOM API‌های جدید و ادغام با کتابخانه‌های third-party مفیده.

    فهرست

  27. تفاوت‌های constructor و getInitialState چیه؟

    وقتی داریم از کلاس‌های ES6 استفاده می‌کنیم باید state‌ رو توی constructor مقداردهی اولیه کنیم و وقتی از React.createClass استفاده می‌کنیم باید از متد getInitialState استفاده کنیم.

    استفاده از کلاس‌های ES6:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          /* initial state */
        };
      }
    }
    

    استفاده از React.createClass:

    const MyComponent = React.createClass({
      getInitialState() {
        return {
          /* initial state */
        };
      },
    });
    

    نکته: React.createClass در ورژن 16 ری‌اکت حذف شده و به جای اون میشه از کلاس‌های ساده جاواسکریپت استفاده کرد.

    فهرست

  28. می‌تونیم یه کامپوننت رو بدون setState ری‌رندر کنیم؟

    در حالت پیش فرض، وقتی state یا prop کامپوننت تغییر‌ می‌کنه، کامپوننت دوباره رندر میشه. اگه متد render به داده‌های دیگه‌ای وابسته باشه، توی فانکشن کامپوننت‌ها می‌تونیم یه state تعریف کنیم و با ست کردن یه مقدار جدید توی اون state عامدانه باعث رندر مجدد کامپوننت بشیم. مثل:

    const [tick, setTick] = useState(0);
    
    const reRender = () => setTick(tick => tick++);
    

    توی مثال بالا ما یه تابع تولید کردیم که با هر بار فراخوانی اون، می‌تونیم انتظار رندر شدن کامپوننت رو داشته باشیم.

    توی کلاس کامپوننت‌ها، می‌تونیم با فراخوانی متد forceUpdate به ری‌اکت بگیم که این کامپوننت نیازه که دوباره رندر بشه.

    component.forceUpdate(callback);
    

    توصیه میشه که از متد ‍‍forceUpdate استفاده نکنیم و توی render فقط از this.props و this.state استفاده کنیم.

    فهرست

  29. تفاوت‌های فراخوانی super() و super(props) توی کلاس کامپوننت‌های ری‌اکت چیه؟

    اگه بخوایم به this.props توی constructor دسترسی پیدا کنیم باید propها رو از طریق متد ‍‍‍super پاس بدیم.

    استفاده از super(props):

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        console.log(this.props); // { name: 'John',... }
      }
    }
    

    استفاده از super:

    class MyComponent extends React.Component {
      constructor(props) {
        super();
        console.log(this.props); // undefined
      }
    }
    

    بیرون از constructor هردو متد مقادیر یکسانی رو برای this.props نشون میدن.

    فهرست

  30. چطوری توی JSX حلقه یا همون لوپ رو داشته باشیم؟

    خیلی ساده می‌تونیم از ‍‍Array.prototype.map با سینتکس _arrow توابع _ ES6 استفاده کنیم، برای مثال آرایه‌ای از آیتم‌های یه آبجکت توی آرایه‌ای از کامپوننت‌ها نوشته میشه:

    <tbody>
      {items.map((item) => (
        <SomeComponent key={item.id} name={item.name} />
      ))}
    </tbody>
    

    نمی‌تونیم با استفاده از حلقه for تکرار رو انجام بدیم:

    <tbody>
      for (let i = 0; i < items.length; i++) {
        <SomeComponent key={items[i].id} name={items[i].name} />
      }
    </tbody>
    

    به خاطر اینکه تگ‌های JSX داخل function calls تبدیل میشن ما نمی‌تونیم از statement‌ها داخل عبارات استفاده کنیم.

    فهرست

  31. توی attributeها چطوری به prop دسترسی داشته باشیم؟

    ری‌اکت و در حقیقت JSX داخل یه attribute استفاده از متفیر به شکل عادی رو پشتیبانی نمی‌کنه.
    مثلا کد پایین کار نمی‌کنه:

    <img className="image" src="images/{this.props.image}" />
    

    اما ما می‌تونیم هر عبارت js رو داخل کرلی براکت({}) به عنوان مقدار کلی attribute قرار بدیم.
    مثلا، تکه کد پایین کار ‌می‌کنه:

    <img className="image" src={"images/" + props.image} />
    

    با استفاده از template strings هم می‌تونیم بنویسیم:

    <img className="image" src={`images/${this.props.image}`} />
    

    فهرست

  32. چطوری یه PropType برای ‌آرایه‌ای از objectها با shape داشته باشیم؟

    اگه بخوایم آرایه‌ای از آبجکت‌ها رو به یه کامپوننت با شکل خاصی پاس بدیم، از React.PropTypes.shape به عنوان یه آرگومان برای React.PropTypes.arrayOf استفاده می‌کنیم.

    ReactComponent.propTypes = {
      arrayWithShape: React.PropTypes.arrayOf(
        React.PropTypes.shape({
          color: React.PropTypes.string.isRequired,
          fontSize: React.PropTypes.number.isRequired,
        })
      ).isRequired,
    };
    

    فهرست

  33. چطوری classهای یه المنت رو به صورت شرطی رندر کنیم؟

    نباید از کرلی براکت({}) داخل کوتیشن('') استفاده کنیم چون به عنوان یه رشته در نظر گرفته میشه.

    <div className="btn-panel {this.props.visible ? 'show': 'hidden'}">
    

    به جاش می‌تونیم کرلی بریس رو به بیرون انتقال بدیم. (فراموش نکنیم که از space بین className‌ها استفاده کنیم.)

    <div className={'btn-panel ' + (this.props.visible ? 'show': 'hidden')}>
    

    با استفاده از Template strings هم می‌تونیم بنویسیم:

    <div className={`btn-panel ${this.props.visible ? 'show': 'hidden'}`}>
    

    فهرست



  1. تفاوت‌های React و ReactDOM چیه؟

    پکیج ری‌اکت شامل React.createElement، React.Component، React.Children و helperهای دیگه که مربوطه به کلاس کامپوننت‌ها و المنت‌ها هستش. می‌تونیم اینا رو به عنوان isomorphic یا universal helpers که واسه ساختن کامپوننت‌ها نیاز داریم, در نظر بگیریم.
    پکیج ‍‍react-dom شامل ReactDOM.render میشه و داخل react-dom/server می‌تونیم با استفاده از متد‌های ReactDOMServer.renderToString و ReactDOMServer.renderToStaticMarkup server-side rendering رو پشتیبانی کنیم.

    فهرست

  2. چرا ReactDOM رو از React جدا کردن؟

    تیم ری‌اکت سعی کرده تمام ویژگی‌های مرتبط با DOM رو جدا کنه و اونا رو توی یه کتابخونه جدا به اسم ReactDom قرار بده. ری‌اکت ورژن ۱۴ اولین نسخه‌ای بود که توش این کتابخونه‌ها از هم جدا شدن. با یه نگاه به بعضی از پکیج‌های ری‌اکت مثل react-native، react-art، react-canvas و react-three مشخص میشه که زیبایی و جوهر ری‌اکت هیچ ربطی به مرورگر‌ها یا DOM نداره. برای ساختن محیط‌های بیشتری که ری‌اکت بتونه رندر بشه، تیم ری‌اکت اومد و پکیج اصلی ری‌اکت رو به دو بخش تقسیم کنه: react و ‍‍react-dom.
    از این طریق تونست کامپوننت‌هایی تولید کنه بین ری‌اکت وب و ری‌اکت نیتیو و... قابل اشتراک باشه.

    فهرست

  3. چطوری از label تو ری‌اکت استفاده کنیم؟

    اگه سعی کنیم که با استفاده از for attribute یه عنصر <label> متصل به یه متن رو رندر کنیم، اون وقت ویژگی HTML بودن رو از دست میده و یه خطا توی کنسول بهمون نشون میده.

    <label for={'user'}>{'User'}</label>
    <input type={'text'} id={'user'} />
    

    از اونجایی که for یه کلمه کلیدی رزرو شده توی جاواسکریپته، به جاش باید از htmlFor استفاده کنیم.

    <label htmlFor={'user'}>{'User'}</label>
    <input type={'text'} id={'user'} />
    

    فهرست

  4. چطوری می‌تونیم چندتا object از استایل‌های درون خطی رو با هم ترکیب کنیم؟

    می‌تونیم از spread operator توی ری‌اکت استفاده کنیم:

    <button style={{...styles.panel.button,...styles.panel.submitButton }}>
      {"Submit"}
    </button>
    

    اگه داریم از ریکت نیتیو استفاده می‌کنیم می‌تونیم از شکل آرایه‌ای استایل‌ها استفاده کنیم:

    <button style={[styles.panel.button, styles.panel.submitButton]}>
      {"Submit"}
    </button>
    

    فهرست

  5. چطوری با resize شدن مرورگر یه ویو رو ری‌رندر کنیم؟

    می‌تونیم به رخداد resize توی componentDidMount گوش کنیم و ابعاد(width و height) رو تغییر بدیم. البته باید حواسمون باشه که این listener رو باید توی متد componentWillUnmount حذفش کنیم.

    class WindowDimensions extends React.Component {
      constructor(props) {
        super(props);
        this.updateDimensions = this.updateDimensions.bind(this);
      }
    
      componentWillMount() {
        this.updateDimensions();
      }
    
      componentDidMount() {
        window.addEventListener("resize", this.updateDimensions);
      }
    
      componentWillUnmount() {
        window.removeEventListener("resize", this.updateDimensions);
      }
    
      updateDimensions() {
        this.setState({
          width: window.innerWidth,
          height: window.innerHeight,
        });
      }
    
      render() {
        return (
          <span>
            {this.state.width} x {this.state.height}
          </span>
        );
      }
    }
    

    همین کار رو با استفاده از هوک‌ها هم میشه انجام داد و برای این کار همین کد رو توی useEffect می‌نویسیم.

    const [dimensions, setDimensions] = useState();
    useEffect(() => {
      window.addEventListener("resize", updateDimensions);
    
      function updateDimensions() {
        setDimensions({
          width: window.innerWidth,
          height: window.innerHeight,
        });
      }
    
      return () => {
        window.removeEventListener("resize", updateDimensions);
      };
    }, []);
    
    return (
      <span>
        {this.state.width} x {this.state.height}
      </span>
    );
    

    فهرست

  6. تفاوت متدهای setState و replaceState چیه؟

    وقتی که از متد setState روی کلاس کامپوننت استفاده می‌کنیم، مقادیر فعلی و قبلی با هم ترکیب می‌شن. replaceState حالت فعلی رو با stateای که می‌خواییم جایگزینش می‌کنه. معمولا اگه از setState برای جایگزین کردن استفاده کنیم، همه کلید‌های قبلی رو پاک کنیم. البته میشه بجای استفاده از replaceState با استفاده از setState بیاییم و state رو برابر با false یا null قرار بدیم.

    فهرست

  7. چطوری به تغییرات state گوش بدیم؟

    توی کلاس کامپوننت‌ها هنگام به روز شدن state یه سری متدها فراخوانی میشه. با استفاده از این متدها میشه state و prop فعلی رو با مقادیر جدید مقایسه کرده و یه سری کار که مدنظر داریم رو انجام بدیم.

    componentWillUpdate(object nextProps, object nextState)
    componentDidUpdate(object prevProps, object prevState)
    

    با استفاده از هوک useEffect هم این امکان بسادگی قابل انجامه و فقط کافیه به dependencyهای این هوک متغیر مربوط به state رو بدیم.

    const [someState, setSomeState] = useState();
    useEffect(() => {
      // code
    }, [someState]);
    

    فهرست

  8. روش توصیه شده برای حذف یک عنصر از آرایه توی state چیه؟

    استفاده از متد Array.prototype.filter آرایه‌ها روش خوبیه.

    برای مثال می‌تونیم یه تابع به اسم removeItem برای به روز کردن state به شکل زیر در نظر بگیریم.

    removeItem(index) {
      this.setState({
        data: this.state.data.filter((item, i) => i !== index)
      })
    }
    

    فهرست

  9. امکانش هست که ری‌اکت رو بدون رندر کردن HTML استفاده کنیم؟

    توی نسخه‌های بالاتر از (>=16.2) میشه. برای مثال تکه کد پایین یه سری مثال برای رندر کردن یه مقدار غیر htmlای هست:

    render() {
      return false
    }
    
    render() {
      return null
    }
    
    render() {
      return []
    }
    
    render() {
      return <React.Fragment></React.Fragment>
    }
    
    render() {
      return <></>
    }
    

    البته حواستون باشه که return کردن undefined کار نخواهد کرد.

    فهرست

  10. چطوری میشه با ری‌اکت یه JSON به شکل beautify شده نشون داد؟

    میشه گفت زیاد ربطی به ری‌اکت یا غیر ری‌اکت بودن برنامه نداره ولی در کل میشه با استفاده از تگ <pre> و استفاده از optionهای متد JSON.stringify این کار رو انجام داد:

    const data = { name: "John", age: 42 };
    
    class User extends React.Component {
      render() {
        return <pre>{JSON.stringify(data, null, 2)}</pre>;
      }
    }
    
    React.render(<User />, document.getElementById("container"));
    

    فهرست

  11. چرا نمی‌تونیم prop رو آپدیت کنیم؟

    فلسفه ساختاری ری‌اکت به شکلیه که propها باید immutable باشن و از بالا به پایین و به صورت سلسه‌مراتبی مقدار بگیرند. به این معنی که پدر هر کامپوننت می‌تونه هر مقداری رو به فرزند پاس بده و فرزند حق دستکاری اونو نداره.

    فهرست


  1. چطوری می‌تونیم موقع لود صفحه روی یه input فوکوس کنیم؟

    میشه با ایجاد یه ref برای المنت input و استفاده از اون توی componentDidMount یا useEffect این‌کار رو کرد:

    const App = () => {
      const nameInputRef = useRef();
      useEffect(() => {
        nameInputRef.current.focus();
      }, []);
    
      return (
        <div>
          <input defaultValue={"Won't focus"} />
          <input ref={nameInputRef} defaultValue={"Will focus"} />
        </div>
      );
    };
    

    همین کد در کلاس کامپوننت:

    class App extends React.Component {
      componentDidMount() {
        this.nameInput.focus();
      }
    
      render() {
        return (
          <div>
            <input defaultValue={"Won't focus"} />
            <input
              ref={(input) => (this.nameInput = input)}
              defaultValue={"Will focus"}
            />
          </div>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById("app"));
    

    فهرست

  2. روش‌های ممکن برای آپدیت کردن object توی state کدوما هستن؟

    1. فراخوانی متد setState با استفاده از یه object برای ترکیب شدن اون:

    • استفاده از Object.assign برای ایجاد یه کپی از object:

    const user = Object.assign({}, this.state.user, { age: 42 });
    this.setState({ user });
    
    • استفاده از عملگر spread:

    const user = {...this.state.user, age: 42 };
    this.setState({ user });
    
    1. فراخوانی setState با یه تابع callback: به این شکل میشه پیاده‌سازی کرد:

    this.setState((prevState) => ({
      user: {
       ...prevState.user,
        age: 42,
      },
    }));
    

    فهرست

  3. چرا توابع به جای object در setState ترجیح داده می‌شوند؟

    ری‌اکت اجازه ترکیب کردن تغییرات state رو با استفاده از متد setState فراهم کرده، همین موضوع باعث بهبود پرفورمنس میشه. توی کلاس کامپوننت‌ها this.props و this.state ممکنه به صورت asynchronous و همزمان به روز بشن، نباید به مقدار اونا برای محاسبه مقدار بعدی اعتماد کرد.

    برای مثال به این شمارنده که درست کار نمی‌کنه دقت کنیم:

    // Wrong
    this.setState({
      counter: this.state.counter + this.props.increment,
    });
    

    روش توصیه شده فراخوانی متد setState با یه تابع بجای object هست. این تابع مقدار state قبلی رو به عنوان پارامتر اول و prop رو به عنوان ورودی دوم می‌گیره و این تابع رو زمانی که مقادیر ورودیش تغییر پیدا کنن فراخوانی می‌کنه.

    // Correct
    this.setState((prevState, props) => ({
      counter: prevState.counter + props.increment,
    }));
    

    فهرست

  4. چطوری می‌‌تونیم نسخه ری‌اکت جاری رو توی محیط اجرایی بفهمیم؟

    خیلی ساده میشه از مقدار React.version برای گرفتن نسخه جاری استفاده کرد.

    const REACT_VERSION = React.version;
    
    ReactDOM.render(
      <div>{`React version: ${REACT_VERSION}`}</div>,
      document.getElementById("app")
    );
    

    فهرست

  5. روش‌های لود کردن polyfill توی CRA کدوما هستن؟

    1. import دستی از core-js:

      یه فایل ایجاد کنیم و اسمشو بزاریم (یه چیزی مثل) polyfills.js و توی فایلindex.js بیایید import کنیمش. کد npm install core-js یا yarn add core-js رو اجرا کنیم و ویژگی‌هایی که لازم داریم رو از corejs بارگذاری کنیم.

    import "core-js/fn/array/find";
    import "core-js/fn/array/includes";
    import "core-js/fn/number/is-nan";
    
    1. استفاده از سرویس Polyfill:

      از سایت polyfill.io CDN واسه گرفتن مقدار شخصی سازی شده براساس مرورگر هر فرد استفاده کنیم و خیلی ساده یه خط کد به index.html اضافه کنیم:

    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.includes"></script>
    

    مثلا توی تکه کد فوق ما برای polyfill کردن Array.prototype.includes درخواست دادیم.

    فهرست



  1. توی CRA چطوری از https به‌جای http استفاده کنیم؟

    برای این‌کار لازمه که کانفیگ HTTPS=true رو برای env جاری ‌ست کنیم، برای این‌کار حتی لازم هم نیست فایل .env بسازیم و می‌تونیم توی فایل package.json بخش scripts رو به شکل پایین تغییر بدیم:

    "scripts": {
      "start": "set HTTPS=true && react-scripts start"
    }
    

    یا حتی به شکل set HTTPS=true && npm start هم میشه تغییر داد.

    فهرست

  2. توی CRA چطوری میشه از مسیر‌های طولانی برای ایمپورت جلوگیری کرد؟

    یه فایل به اسم .env توی مسیر اصلی پروژه ایجاد می‌کنیم و مسیر مورد نظر خودمون رو اونجا می‌نویسم:

    NODE_PATH=src/app
    

    بعد از این تغییر سرور develop رو ریستارت می‌کنیم بعدش دیگه می‌تونیم هر چیزی رو از مسیر src/app بارگذاری کنیم و لازم هم نباشه مسیر کاملشو بهش بدیم. این‌کار رو میشه با بخش module resolve توی webpack هم انجام داد.

    فهرست

  3. چطوری میشه Google Analytics رو به react-router اضافه کرد؟

    یه listener به آبجکت history اضافه می‌کنیم تا بتونیم لود شدن صفحه رو track کنیم:

    history.listen(function (location) {
      window.ga("set", "page", location.pathname + location.search);
      window.ga("send", "pageview", location.pathname + location.search);
    });
    

    توی نسخه ۶ از react-router-dom دسترسی مستقیم به history برداشته شده تا پشتیبانی از suspense راحت‌تر باشه، توی این نسخه میشه از useLocation به شکل زیر استفاده کرد:

    const location = useLocation();
    
    useEffect(() => {
      window.ga("set", "page", location);
      window.ga("send", "pageview", location);
    }, [location]);
    

    فهرست

  4. چطوری یه کامپوننت رو هر ثانیه به روز کنیم؟

    لازمه که از setInterval استفاده کنیم تا تغییرات رو اعمال کنیم و البته حواسمون هست که موقع unmount این interval رو حذف کنیم که باعث memory leak نشه.

    const intervalRef = useRef();
    
    useEffect(() => {
       intervalRef.current = setInterval(() => this.setState({ time: Date.now() }), 1000);
    
       return () => {
         clearInterval(intervalRef.current);
       }
    }, [location]);
    

    توی کلاس کامپوننت هم به شکل:

    componentDidMount() {
      this.interval = setInterval(() => this.setState({ time: Date.now() }), 1000)
    }
    
    componentWillUnmount() {
      clearInterval(this.interval)
    }
    

    فهرست


  1. برای استایل‌دهی‌های درون خطی چطوری باید پیشوند‌های مخصوص مرورگرها رو اضافه کرد؟

    ری‌اکت به شکل اتوماتیک پیشوند‌های مخصوص مرورگرها روی css رو اعمال نمی‌کنه. لازمه که تغییرات رو به شکل دستی اضافه کنیم.

    <div
      style={{
        transform: "rotate(90deg)",
        WebkitTransform: "rotate(90deg)", // note the capital 'W' here
        msTransform: "rotate(90deg)", // 'ms' is the only lowercase vendor prefix
      }}
    />
    

    فهرست

  2. چطوری کامپوننت‌های ری‌اکت رو با es6 می‌تونیم import و export کنیم؟

    لازمه که از default برای export کردن کامپوننت‌ها استفاده کنیم

    import React from "react";
    import User from "user";
    
    export default class MyProfile extends React.Component {
      render() {
        return <User type="customer">//...</User>;
      }
    }
    

    با استفاده از کلمه کلیدی export default می‌تونیم کامپوننت MyProfile(یا هر متغیر و کلاس دیگه‌ای) رو به عنوان یه عضو از ماژول فعلی معرفی کرد و بعد از این، برای import کردن اون لزومی به استفاده از عنوان این کامپوننت نیست.

    فهرست



  1. استثنایی که برای نام‌گذاری کامپوننت اجازه استفاده از حرف کوچک رو میده چیه؟

    همه کامپوننت‌های ری‌اکت لازمه که با حرف بزرگ شروع بشن، ولی توی این مورد هم یه سری استثناها وجود داره. تگ‌هایی که با property و عملگر dot کار می‌کنن رو میشه به عنوان کامپوننت‌هایی با حرف کوچک تلقی کرد. برای مثال این تگ می‌تونه syntax معتبری برای ری‌اکت باشه که با حروف کوچیک شروع میشه:

    const Component = () => {
       return (
           <obj.component /> // `React.createElement(obj.component)`
       )
    }
    

    فهرست

  2. چرا تابع سازنده کلاس کامپوننت یکبار صدا زده میشه؟

    الگوریتم reconciliation ری‌اکت بعد از رندر کردن کامپوننت با بررسی رندرهای مجدد، بررسی می‌کنه که این کامپوننت قبلا رندر شده یا نه و اگه قبلا رندر شده باشه، تغییرات جدید رو روی همون instance قبلی رندر می‌کنه و instance جدیدی ساخته نمیشه، پس تابع سازنده هم تنها یکبار صدا زده میشه.

    فهرست

  3. توی ری‌اکت چطوری مقدار ثابت تعریف کنیم؟

    می‌تونیم از فیلد استاتیک ES7 برای تعریف ثابت استفاده کنیم.

    class MyComponent extends React.Component {
      static DEFAULT_PAGINATION = 10;
    }
    

    فیلدهای استاتیک بخشی از فیلدهای کلاس(class properties) هستن که توی پروپوزال stage 3 معرفی شدن.

    فهرست


  1. چطوری توی برنامه event کلیک شدن رو trigger کنیم؟

    می‌تونیم از ref برای بدست آوردن رفرنس HTMLInputElement مورد نظر استفاده کنیم و object بدست اومده رو توی یه متغیر یا property نگهداری کنیم، بعدش از اون رفرنس می‌تونیم برای اعمال رخداد کلیک استفاده کنیم
    که HTMLElement.click رو فراخوانی می‌کنه. این فرآیند توی دو گام قابل انجام هستش:

    1. ایجاد ref توی متد render:

    <input ref={inputRef} />
    
    1. اعمال رخداد click توی event handler:

    inputRef.click();
    

    فهرست

  2. آیا استفاده از async/await توی ری‌اکت ممکنه؟

    اگه بخواییم از async/await توی ری‌اکت استفاده کنیم، لازمه که Babel و پلاگین transform-async-to-generator رو استفاده کنیم. توی React Native اینکار با Babel و یه سری transformها انجام میشه.

    فهرست

  3. ساختار پوشه‌بندی معروف برا ری‌اکت چطوریه؟

    دو روش معروف برای پوشه‌های ری‌اکت وجود داره:

    1. گروه بندی براساس ویژگی یا route:

      یک روش معروف قراردادن فایل‌های CSS، JS و تست‌ها کنارهم به ازای هر ویژگی یا route هست، مثل این ساختار:

        common/
        ├─ Avatar.js
        ├─ Avatar.css
        ├─ APIUtils.js
        └─ APIUtils.test.js
        feed/
        ├─ index.js
        ├─ Feed.js
        ├─ Feed.css
        ├─ FeedStory.js
        ├─ FeedStory.test.js
        └─ FeedAPI.js
        profile/
        ├─ index.js
        ├─ Profile.js
        ├─ ProfileHeader.js
        ├─ ProfileHeader.css
        └─ ProfileAPI.js
    
    1. گروه‌بندی بر اساس ماهیت فایل:

      یک سبک مشهور دیگر گروه‌بندی فایل‌ها براساس ماهیت اونهاست که حالا همین روش هم می‌تونه به شکل‌های مختلف اجرا بشه ولی ساختار پایین می‌تونه یه مثال برای این روش باشه:

        api/
        ├─ APIUtils.js
        ├─ APIUtils.test.js
        ├─ ProfileAPI.js
        └─ UserAPI.js
        components/
        ├─ Avatar.js
        ├─ Avatar.css
        ├─ Feed.js
        ├─ Feed.css
        ├─ FeedStory.js
        ├─ FeedStory.test.js
        ├─ Profile.js
        ├─ ProfileHeader.js
        └─ ProfileHeader.css
    

    فهرست



  1. پکیج‌های مشهور برای انیمیشن کدوما هستن؟

    React Transition Group، React Spring و React Motion پکیج‌های مشهور برای انیمیشن برای ری‌اکت هستن.

    فهرست

  2. مزایای ماژول‌های style چیه؟

    خیلی توصیه میشه که از استایل‌دهی‌های سخت و مستقیم برای کامپوننت‌ها پرهیز کنیم. هرمقداری که فقط در یک کامپوننت خاصی مورد استفاده قرار می‌گیره، بهتره که درون همون فایل لود بشه.

    برای مثال، این استایل‌ها می‌تونن تو یه فایل دیگه انتقال پیدا کنن:

    export const colors = {
      white,
      black,
      blue,
    };
    
    export const space = [0, 8, 16, 32, 64];
    

    و توی موقعی که نیاز داریم از اون فایل مشخص لود کنیمشون:

    import { space, colors } from "./styles";
    

    فهرست

  3. معروف‌ترین linterهای ری‌اکت کدوما هستن؟

    ESLint یه linter برای JavaScript هستش. یه سری کتابخونه برای کمک به کدنویسی تو سبک‌های مشخص و استاندارد برای eslint وجود داره. یکی از معروف‌ترین پلاگین‌های موجود eslint-plugin-react هست.
    به صورت پیش‌فرض این پلاگین یه سری از best practiceها رو برای کدهای نوشته شده بررسی می‌کنه و یه مجموعه‌ از قوانین رو برای کدنویسی الزام می‌کنه. پلاگین مشهور دیگه eslint-plugin-jsx-a11y هستش، که برای بررسی نکات و ملزومات معروف در زمینه accessibility کمک‌ می‌کنه. چرا که JSX یه سینتکس متفاوت‌تری از HTML ارائه می‌کنه، مشکلاتی که ممکنه مثلا با alt و tabindex پیش میاد رو با این پلاگین میشه متوجه شد.

    فهرست

  4. چطوری باید توی کامپوننت درخواست api call بزنیم؟

    می‌تونیم از کتابخونه‌های AJAX مثل Axios یا حتی از fetch که به صورت پیش‌فرض تو مرورگر وجود داره استفاده کنیم. لازمه که توی Mount درخواست API رو انجام بدیم و برای به روز کردن کامپوننت می‌تونیم از setState استفاده کنیم تا داده بدست اومده رو توی کامپوننت نشون بدیم.

    برای مثال، لیست کارمندان از API گرفته میشه و توی state نگهداری میشه:

    const MyComponent = () => {
      const [employees, setEmployees] = useState([]);
      const [error, setError] = useState(null);
    
      useEffect(() => {
        fetch("https://api.example.com/items")
         .then((res) => res.json())
         .then(
            (result) => {
              setEmployees(result.employees);
            },
            (error) => {
              setError(error);
            }
          );
      }, []);
    
      return error ? (
        <div>Error: {error.message}</div>
      ): (
        <ul>
          {employees.map((employee) => (
            <li key={employee.name}>
              {employee.name}-{employee.experience}
            </li>
          ))}
        </ul>
      );
    };
    

    همین کد روی کلاس کامپوننت به شکل زیر اجرا میشد:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          employees: [],
          error: null,
        };
      }
    
      componentDidMount() {
        fetch("https://api.example.com/items")
         .then((res) => res.json())
         .then(
            (result) => {
              this.setState({
                employees: result.employees,
              });
            },
            (error) => {
              this.setState({ error });
            }
          );
      }
    
      render() {
        const { error, employees } = this.state;
        if (error) {
          return <div>Error: {error.message}</div>;
        } else {
          return (
            <ul>
              {employees.map((employee) => (
                <li key={employee.name}>
                  {employee.name}-{employee.experience}
                </li>
              ))}
            </ul>
          );
        }
      }
    }
    

    فهرست



  1. render props چیه؟

    Render Props یه تکنیک ساده برای به اشتراک گذاری کامپوننت بین کامپوننت‌های دیگه‌ـست که با استفاده از یه prop که یه تابع یا یه کامپوننت رو بهش دادیم انجام میشه. کامپوننت زیر از همین روش برای پاس دادن یه React element استفاده می‌کنه و توی کامپوننت پایین این prop رو یه شکل یه تابع فراخوانی می‌کنیم و چون یه تابع هست، میتونیم بهش هر مقداری که میخواییم بیاریم این سمت رو پاس بدیم.

    <DataProvider render={(data) => <h1>{`Hello ${data.target}`}</h1>} />
    

    کتابخونه‌هایی مثل React Router و DownShift از این پترن استفاده می‌کنن.



React Router


  1. React Router چیه؟

    React Router یه کتابخونه قدرتمند برای جابجایی سریع بین صفحات و flowهای مختلفه که برپایه ری‌اکت نوشته شده و امکان sync کردن آدرس وارد شده با صفحات رو توی محیط‌های مختلف فراهم می‌کنه.

    فهرست

  2. ارتباط React Router و کتابخونه history چیه؟

    React Router یه wrapper روی کتابخونه history هست که اعمال اجرایی بر روی window.history رو با استفاده از ابجکت‌های hash و browser مدیریت می‌کنه. البته این کتابخونه یک نوع دیگه از historyها به اسم memory history رو هم معرفی می‌کنه که برای محیط‌هایی که به صورت عمومی از history پشتیبانی نمی‌کنن کاربرد داره. مثل محیط توسعه برنامه موبایل با (React Native) یا محیط‌های unit test و Nodejs.

    فهرست

  3. کامپوننت‌های router توی نسخه۴ کدوما هستن؟

    React Router v4 سه نوع مختلف از کامپوننت رووتر(<Router>) رو معرفی‌می‌کنه:

    1. <BrowserRouter>

    2. <HashRouter>

    3. <MemoryRouter>

    کامپوننت‌های فوق به ترتیب browser، hash، و memory history درست می‌کنن. React Router v4 ساخت history رو براساس context ارائه شده به آبجکت router انجام می‌ده و همین موضوعه که باعث میشه بتونیم از این کتابخونه توی محیط‌های مختلف استفاده کنیم.

    فهرست

  4. هدف از متدهای push و replace توی history چیه؟

    هر شئ از آبجکت history دو تا متد برای کار با state مرورگر ارائه می‌ده.

    1. push

    2. replace

    اگه به history به شکل یک آرایه از مسیرهای بازدید شده نگاه کنیم، push یک جابجایی جدید به مسیر اضافه می‌کنه و replace مسیر فعلی رو با یه مسیر جدید جایگزین می‌کنه.

    فهرست

  5. چطوری توی برنامه به route خاص جابجا بشیم؟

    روش‌های مختلفی برای جابجایی در برنامه و توسط کد وجود داره که پایین لیست می‌کنیم، ولی روش آخر(استفاده از هوک‌ها) بهترین و ساده‌ترین روش توی کامپوننت‌های تابعی هست.

    1. استفاده از تابع مرتبه بالاتر(higher-order) withRouter:

      متد withRouter آبجکت history رو به عنوان یه prop به کامپوننت اضافه می‌کنه. روی این prop به متدهای push و replace دسترسی داریم که به‌سادگی می‌تونه مسیریابی بین routeها رو فراهم کنه و نیاز به context رو رفع کنه.

    import { withRouter } from "react-router-dom"; // this also works with 'react-router-native'
    
    const Button = withRouter(({ history }) => (
      <button
        type="button"
        onClick={() => {
          history.push("/new-location");
        }}
      >
        {"Click Me!"}
      </button>
    ));
    
    1. استفاده از کامپوننت <Route> و پترن render props:

      کامپوننت <Route> همون prop که متد withRouter به کامپوننت میده رو به کامپوننت میده.

    import { Route } from "react-router-dom";
    
    const Button = () => (
      <Route
        render={({ history }) => (
          <button
            type="button"
            onClick={() => {
              history.push("/new-location");
            }}
          >
            {"Click Me!"}
          </button>
        )}
      />
    );
    
    1. استفاده از context:

      استفاده از این مورد توصیه نمی‌شه و ممکنه به زودی deprecate شود.

    const Button = (props, context) => (
      <button
        type="button"
        onClick={() => {
          context.history.push("/new-location");
        }}
      >
        {"Click Me!"}
      </button>
    );
    
    Button.contextTypes = {
      history: React.PropTypes.shape({
        push: React.PropTypes.func.isRequired,
      }),
    };
    
    1. استفاده از هوک‌های موجود:

      هوک‌هایی برای دسترسی به history و params در این کتابخونه وجود داره مثل useHistory یا حتی توی نسخه‌ ۶ به بعد هوک useNavigate که راحت‌تر می‌تونه امکان navigate بین صفحات رو فراهم کنه:

    const Page = (props, context) => {
      const history = useHistory();
      const location = useLocation();
      const { slug } = useParams();
    
      return (
        <button
          type="button"
          onClick={() => {
            history.push("/new-location");
          }}
        >
          {"Click Me!"}
        </button>
      );
    };
    

    نسخه ۶:

    const Page = (props, context) => {
      const navigate = useNavigate();
    
      return (
        <button
          type="button"
          onClick={() => {
            navigate("/new-location");
          }}
        >
          {"Click Me!"}
        </button>
      );
    };
    

    فهرست

  6. چطوری میشه query پارامترها رو توی ری‌اکت روتر نسخه۴ گرفت؟

    ساده‌ترین راه برای دسترسی به paramهای آدرس استفاده از هوک useParams هست.

    const { slug } = useParams();
    
    console.log(`slug query param`, slug);
    

    فهرست

  7. دلیل خطای "Router may have only one child element" چیه؟

    باید کامپوننت Route رو توی بلاک <Switch> قرار بدیم چون همین کامپوننت <Switch> چون Switch هست که باعث میشه منحصرا فقط یه route با مسیر فعلی تطابق پیدا کنه و کامپوننت اون route توی صفحه رندر بشه. اولش لازمه که Switch رو import کنیم:

    import { Switch, Router, Route } from "react-router";
    

    بعدش routeها رو <Switch> تعریف می‌کنیم:

    <Router>
      <Switch>
        <Route {/*... */} />
        <Route {/*... */} />
      </Switch>
    </Router>
    

    فهرست

  8. چطوری میشه به متد history.push پارامتر اضافه کرد؟

    همونطوری که می‌دونیم موقع جابجایی میشه یه object به history پاس بدیم که یه سری گزینه‌ها رو برامون قابل کانفیگ می‌کنه:

    this.props.history.push({
      pathname: "/template",
      search: "?name=sudheer",
      state: { detail: response.data },
    });
    

    این کانفیگ‌ها یکیش search هست که می‌تونه پارامتر موردنظر ما رو به مسیر مورد نظر بفرسته.

    فهرست

  9. چطوری میشه صفحه ۴۰۴ ساخت؟

    کامپوننت <Switch> اولین فرزند <Route>ای که با درخواست موجود تطابق داشته باشه رو رندر می‌کنه. از اونجایی که یه <Route> بدون path یا با path * همیشه مطابق با درخواست‌هاست، پس هنگام خطای ۴۰۴ این مورد برای رندر استفاده میشه.

    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/user" component={User} />
      <Route component={NotFound} />
    </Switch>
    

    فهرست


  1. توی ری‌اکت روتر نسخه۴ چطوری میشه history رو گرفت؟

    1. می‌تونیم یه ماژول درست کنیم که object history رو میده و هرجایی خواستیم از این فایل استفاده کنیم.

      برای مثال فایل history.js رو ایجاد کنید:

    import { createBrowserHistory } from "history";
    
    export default createBrowserHistory({
      /* pass a configuration object here if needed */
    });
    
    1. می‌تونیم از کامپوننت <Router> بجای رووترهای پیش‌فرض استفاده کنیم. فایل history.js بالا رو توی فایل index.js لود می‌کنیم:

    import { Router } from "react-router-dom";
    import history from "./history";
    import App from "./App";
    
    ReactDOM.render(
      <Router history={history}>
        <App />
      </Router>,
      holder
    );
    
    1. البته میشه از متد push مثل آبجکت پیش‌فرض history استفاده کنیم:

    // some-other-file.js
    import history from "./history";
    
    history.push("/go-here");
    

    نکته: روی نسخه ۶ دسترسی مستقیم به history حذف شده و برای هر کار یه هوک مختص به اون کار مهیا شده.

    فهرست

  2. چطوری بعد از لاگین به شکل خودکار ریدایرکت کنیم؟

    پکیج react-router امکان استفاده از کامپوننت <Redirect> رو توی React Router فراهم می‌کنه. رندر کردن <Redirect> باعث جابجایی به مسیر پاس داده شده میشه. دقیقا مثل ریدایرکت سمت سرور، path مسیر جدید با path فعلی جایگزین می‌شه.

    import React, { Component } from "react";
    import { Redirect } from "react-router";
    
    const Component = () => {
      if (isLoggedIn === true) {
        return <Redirect to="/your/redirect/page" />;
      } else {
        return <div>{"Login Please"}</div>;
      }
    }
    


چندزبانگی ری‌اکت


  1. React-Intl چیه؟

    React Intl یه کتابخونه برای آسان نمودن توسعه برنامه‌های چند زبانه‌ـست. این کتابخونه از مجموعه‌ای از کامپوننت‌ها و APIها برای فرمت‌بندی رشته‌ها، تاریخ و اعداد رو برای ساده‌سازی فرآیند چندزبانگی فراهم می‌کنه. React Intl بخشی از FormatJS هست که امکان اتصال به ری‌اکت رو با کامپوننت‌های خودش فراهم می‌کنه.

    فهرست

  2. اصلی‌ترین ویژگی‌های React Intl کدوما هستن؟

    1. نمایش اعداد با جداکننده‌های مشخص

    2. نمایش تاریخ و ساعت با فرمت درست

    3. نمایش تاریخ بر اساس زمان حال

    4. امکان استفاده از لیبل‌ها توی string

    5. پشتیبانی از بیش از ۱۵۰ زبان

    6. اجرا توی محیط مرورگر و node

    7. دارا بودن استانداردهای داخلی

    فهرست

  3. دو روش فرمت کردن توی React Intl کدوما هستن؟

    این کتابخونه از دو روش برای فرمت‌بندی رشته‌ها، اعداد و تاریخ استفاده می‌کنه: کامپوننت‌های ری‌اکتی و API.

    <FormattedMessage
      id={"account"}
      defaultMessage={"The amount is less than minimum balance."}
    />
    
    const messages = defineMessages({
      accountMessage: {
        id: "account",
        defaultMessage: "The amount is less than minimum balance.",
      },
    });
    
    formatMessage(messages.accountMessage);
    

    فهرست

  4. چطوری از FormattedMessage به عنوان یه placeholder میشه استفاده کرد؟

    کامپوننت <Formatted... /> از react-intl بجای بازگرداندن string یه المنت برگشت میده و به همین دلیل نمیشه ازش به عنوان placeholder یا alt و... استفاده کرد. اگه جایی لازم شد یه پیامی رو اینجور جاها استفاده کنیم باید از formatMessage استفاده کنیم. می‌تونیم شي intl رو با استفاده از HOC injectIntl به کامپوننت موردنظر inject کنیم و بعدشم می‌تونیم از متد formatMessage روی این شي استفاده کنید.

    import React from "react";
    import { injectIntl, intlShape } from "react-intl";
    
    const MyComponent = ({ intl }) => {
      const placeholder = intl.formatMessage({ id: "messageId" });
      return <input placeholder={placeholder} />;
    };
    
    MyComponent.propTypes = {
      intl: intlShape.isRequired,
    };
    
    export default injectIntl(MyComponent);
    

    فهرست

  5. چطوری میشه locale فعلی رو توی React Intl بدست آورد؟

    می‌تونیم با استفاده از injectIntl به locale فعلی رو دسترسی داشته باشیم:

    import { injectIntl, intlShape } from "react-intl";
    
    const MyComponent = ({ intl }) => (
      <div>{`The current locale is ${intl.locale}`}</div>
    );
    
    MyComponent.propTypes = {
      intl: intlShape.isRequired,
    };
    
    export default injectIntl(MyComponent);
    

    فهرست

  6. چطوری با استفاده از React Intl یه تاریخ رو فرمت‌بندی کنیم؟

    می‌تونیم با استفاده از HOC injectIntl به متد formatDate توی کامپوننت خودمون دسترسی داشته باشیم. این متد به صورت داخلی توسط FormattedDate استفاده میشه و مقدار string تاریخ فرمت بندی شده رو برمی‌گردونه.

    import { injectIntl, intlShape } from "react-intl";
    
    const stringDate = this.props.intl.formatDate(date, {
      year: "numeric",
      month: "numeric",
      day: "numeric",
    });
    
    const MyComponent = ({ intl }) => (
      <div>{`The formatted date is ${stringDate}`}</div>
    );
    
    MyComponent.propTypes = {
      intl: intlShape.isRequired,
    };
    
    export default injectIntl(MyComponent);
    



تست ری‌اکت


  1. توی تست ری‌اکت Shallow Renderer چیه؟

    Shallow rendering برای نوشتن یونیت تست توی ری‌اکت کاربرد داره. این روش بهمون این امکان رو میده که به عمق یک مرتبه کامپوننت موردنظرمون رو رندر کنیم و مقدار بازگردانی شده رو بدون اینکه نگران عملکرد کامپوننت‌های فرزند باشیم، ارزیابی کنیم.

    برای مثال، اگه کامپوننتی به شکل زیر داشته باشیم:

    function MyComponent() {
      return (
        <div>
          <span className={"heading"}>{"Title"}</span>
          <span className={"description"}>{"Description"}</span>
        </div>
      );
    }
    

    می‌تونیم انتظار اجرا به شکل پایین رو داشته باشیم:

    import ShallowRenderer from "react-test-renderer/shallow";
    
    // in your test
    const renderer = new ShallowRenderer();
    renderer.render(<MyComponent />);
    
    const result = renderer.getRenderOutput();
    
    expect(result.type).toBe("div");
    expect(result.props.children).toEqual([
      <span className={"heading"}>{"Title"}</span>,
      <span className={"description"}>{"Description"}</span>,
    ]);
    

    فهرست

  2. پکیج TestRenderer توی ری‌اکت چیه؟

    این پکیج یه renderer معرفی می‌کنه که می‌تونیم ازش برای رندر کردن کامپوننت‌ها و تبدیل اونا به یه آبجکت pure JavaScript استفاده کنیم بدون اینکه وابستگی به DOM یا محیط اجرایی موبایلی داشته باشیم. این پکیج برای گرفتن snapshot از سلسله مرتب view(یه چیزی شبیه به درخت DOM) که توسط ReactDOM یا React Native درست میشه رو بدون نیاز به مرورگر یا jsdom فراهم می‌کنه.

    import TestRenderer from "react-test-renderer";
    
    const Link = ({ page, children }) => <a href={page}>{children}</a>;
    
    const testRenderer = TestRenderer.create(
      <Link page={"https://www.facebook.com/"}>{"Facebook"}</Link>
    );
    
    console.log(testRenderer.toJSON());
    // {
    //   type: 'a',
    //   props: { href: 'https://www.facebook.com/' },
    //   children: [ 'Facebook' ]
    // }
    

    فهرست

  3. هدف از پکیج ReactTestUtils چیه؟

    ReactTestUtils توی پکیج with-addons ارائه شده و اجازه اجرای یه سری عملیات روی DOMهای شبیه‌سازی شده رو برای انجام یونیت‌ تست‌ها ارائه می‌ده.

    فهرست

  4. Jest چیه؟

    Jest یه فریم‌ورک برای یونیت تست کردن جاواسکریپت هستش که توسط فیس بوک و براساس Jasmine ساخته شده. Jest امکان ایجاد اتوماتیک mock(دیتا یا مقدار ثابت برای تست) و محیط jsdom رو فراهم می‌کنه.

    فهرست

  5. مزایای jest نسبت به jasmine کدوما هستن؟

    یه سری برتری‌هایی نسبت بهJasmine داره:

    • می‌تونه به صورت اتوماتیک تست‌ها رو توی سورس کد پیدا و اجرا کنه

    • به صورت اتوماتیک می‌تونه وابستگی‌هایی که داریم رو mock کنه

    • امکان تست کد asynchronous رو به شکل synchronously فراهم می‌کنه

    • تست‌ها رو با استفاده از یه پیاده‌سازی مصنوعی از DOM(jsdom) اجرا می‌کنه و بواسطه اونه که تست‌ها قابلیت اجرا روی cli رو دارن

    • تست‌ها به شکل موازی و همزمان اجرا می‌شن و می‌تونن توی مدت زمان زودتری تموم شن

    فهرست

  6. یه مثال ساده از تست با jest بزن؟

    خب بیایین یه تست برای تابعی که جمع دو عدد رو توی فایل sum.js برامون انجام میده بنویسیم:

    const sum = (a, b) => a + b;
    
    export default sum;
    

    یه فایل به اسم sum.test.js ایحاد می‌کنیم که تست‌هامون رو توش بنویسیم:

    import sum from "./sum";
    
    test("adds 1 + 2 to equal 3", () => {
      expect(sum(1, 2)).toBe(3);
    });
    

    و بعدش به فایل package.json بخش پایین رو اضافه می‌کنیم:

    {
      "scripts": {
        "test": "jest"
      }
    }
    

    در آخر، دستور yarn test یا npm test اجرا می‌کنیم و Jest نتیجه تست رو برامون چاپ می‌کنه:

    $ yarn test
    PASS./sum.test.js
    ✓ adds 1 + 2 to equal 3 (2ms)
    



React Redux


  1. Flux چیه؟

    Flux یه الگوی طراحی برنامه‌ـست که به عنوان جایگزینی برای اکثر پترن‌های MVC سنتی به کار میره. در حقیقت یه کتابخونه یا فریم‌ورک نیست و یه معماری برای تکمیل کارکرد ری‌اکت با مفهوم جریان داده یک طرفه(Unidirectional Data Flow) به کار میره. فیس‌بوک از این پترن به شکل داخلی برای توسعه ری‌اکت بهره می‌گیره.

    جریان کار بین dispatcher، store‌ها و viewهای کامپوننت‌ها با ورودی و خروجی مشخص به شکل صفحه بعد خواهد بود:

    flux

    فهرست

  2. Redux چیه؟

    Redux یه state manager(مدیریت کننده حالت) قابل پیش‌بینی برای برنامه‌های جاواسکریپت‌ـه که برپایه دیزاین پترن Flux ایجاد شده. Redux می‌تونه با ری‌اکت یا هر کتابخونه دیگه‌ای استفاده بشه. کم حجمه(حدود 2 کیلوبایت) و هیچ وابستگی به کتابخونه دیگه‌ای نداره.

    فهرست

  3. مبانی اصلی ریداکس کدوما هستن؟

    Redux از سه اصل بنیادی پیروی می‌کنه:

    1. یک مرجع کامل و همواره درست: حالت موجود برا کل برنامه در یک درخت object و توی یه store نگهداری میشه. همین یکی بودن store باعث میشه دنبال کردن تغییرات در زمان توسعه و حتی دیباگ کردن برنامه ساده‌تر باشه.

    2. State فقط قابل خواندن است: تنها روش ایجاد تغییر در store استفاده از action هستش و نتیجه اجرای این action یک object خواهد بود که رخداد پیش اومده رو توصیف می‌کنه. به این ترتیب مطمئن میشیم که تغییرات فقط با action انجام میشن و هر دیتایی توی store باشه توسط خودمون پر شده.

    3. تغییرات با یه سری تابع pure انجام میشن: برای مشخص کردن نحوه انجام تغییرات در store باید reducer بنویسیم. Reducerها فقط یه سری توابع pure هستن که حالت قبلی و action رو به عنوان پارامتر می‌گیرن و حالت بعدی رو برگشت میدن.

    فهرست


  1. کاستی‌های redux نسبت به flux کدوما هستن؟

    بجای گفتن کاستی‌ها بیایین مواردی که می‌دونیم موقع استفاده از Redux بجای Flux داریم رو بگیم:

    1. باید یاد بگیریم که mutation انجام ندیم: Flux در مورد mutate کردن داده نظری نمی‌دهد، ولی Redux از mutate کردن داده جلوگیری می‌کنه و پکیج‌های مکمل زیادی برای مطمئن شدن از mutate نشدن state توسط برنامه‌نویس ایجاد شده‌اند. این مورد رو میشه فقط برای محیط توسعه با پکیجی مثل redux-immutable-state-invariant، Immutable.js یا آموزش تیم برای نوشتن کد بدون mutate دیتا محقق کرد.

    2. باید توی انتخاب پکیج‌ها محتاطانه عمل کنید: Flux به شکل خاص کاری برای حل مشکلاتی مثل undo/redo، persist کردن داده یا مدیریت فرم‌ها انجام نداده است. در عوض Redux کلی middleware و مکمل store برای محقق ساختن همچین نیاز‌های داره.

    3. شاید هنوز یه جریان داده خوشگل نداشته باشه در حال حاضر Flux بهمون اجازه یه type check استاتیک خوب رو میده ولی Redux هنوز پشتیبانی خوبی نداره براش.

    فهرست

  2. تفاوت‌های mapStateToProps و mapDispatchToProps چی هست؟

    mapStateToProps یه ابزار برای دریافت به روزشدن‌های stateها توی کامپوننت هستش (که توسط یه کامپوننت دیگه به روز شده):

    const mapStateToProps = (state) => {
      return {
        todos: getVisibleTodos(state.todos, state.visibilityFilter),
      };
    };
    

    mapDispatchToProps یه ابزار برای آوردن action برای فراخوانی تو کامپوننت ارائه میده (actionای که می‌خواییم dispatch کنیم و ممکنه state رو عوض کنه):

    const mapDispatchToProps = (dispatch) => {
      return {
        onTodoClick: (id) => {
          dispatch(toggleTodo(id));
        },
      };
    };
    

    توصیه میشه که همیشه از روش “object shorthand” برای دسترسی به mapDispatchToProps استفاده بشه

    Redux این action رو توی یه تابع دیگه قرار میده که تقریبا میشه یه چیزی مثل (…args) => dispatch(onTodoClick(…args)) و تابعی که خودش به عنوان wrapper ساخته رو به کامپوننت مورد نظر ما میده.

    const mapDispatchToProps = {
      onTodoClick,
    };
    

    و البته هوک‌های ریداکس برای دسترسی به state و انجام action مورد نظر هم خیلی کاربرد داره.

    فهرست

  3. توی ریدیوسر می‌تونیم یه actionی رو dispatch کنیم؟

    Dispatch کردن action توی reducer یه آنتی پترن محسوب میشه. reducer نباید هیچ ساید‌افکتی داشته باشه، فقط باید خیلی ساده state قبلی و action فعلی رو بگیره و state جدید رو بده. این‌کار رو اگه با افزودن یه سری listeners و dispatch کردن با تغییرات reducer هم انجام بدیم باز باعث ایجاد actionهای تودرتو میشه و می‌تونه ساید افکت داشته باشه،

    فهرست

  4. چطوری میشه خارج از کامپوننت میشه store ریداکس دسترسی داشت؟

    لازمه که store رو از یه ماژول که با createStore ایجاد شده بارگذاری کنیم. البته حواسمون باشه برای انجام این مورد نباید اثری روی window به شکل global ایجاد کنیم.

    const store = createStore(myReducer);
    
    export default store;
    

    فهرست

  5. اشکالات پترن MVW کدوما هستن؟

    1. مدیریت DOM خیلی هزینه‌بر هست و می‌تونه باعث کندی و ناکارآمد شدن برنامه بشه.

    2. بخاطر circular dependencies(وابستگی چرخشی) یه مدل پیچیده بین modelها و viewها ایجاد میشه.

    3. بخاطر تعامل زیاد برنامه تغییرات خیلی زیادی رخ میده(مثل Google Docs).

    4. روش ساده‌ و بدون دردسری برای undo کردن(برگشت به عقب) نیست.

    فهرست

  6. تشابهی بین Redux و RxJS هست؟

    این دو کتابخونه خیلی متفاوتن و برای اهداف متفاوتی استفاده میشن، ولی یه سری تشابه‌های ریزی دارن.

    Redux یه ابزار برای مدیریت state توی کل برنامه‌ست. اکثرا هم به عنوان یه معماری برای ایجاد رابط کاربری استفاده میشه. RxJS یه کتابخونه برای برنامه‌نویسی reactive(کنش گرا) هستش. اکثرا هم برای انجام تسک‌های asynchronous توی جاواسکریپت به کار میره. می‌تونیم بهش به عنوان یه معماری بجای Promise نگاه کنیم. Redux هم از الگوی Reactive استفاده می‌کنه چون Store ریداکس reactive هستش. Store میاد actionها رو از دور می‌بینه و تغییرات لازم رو توی خودش ایجاد می‌کنه. RxJS هم از الگوی Reactive پیروی می‌کنه، ولی بجای اینکه خودش این architecture رو بسازه میاد به شما یه سری بلاک‌های سازنده به اسمObservable میده که باهاش بتونید الگوی reactive رو اجرا کنید.
    فهرست

  7. چطوری میشه یه اکشن رو موقع لود dispatch کرد؟

    خیلی ساده میشه اون action رو موقع mount اجرا کرد و موقع render دیتای مورد نیاز رو داشت.

    const App = (props) => {
      useEffect(() => {
        props.fetchData();
      }, []);
    
      return props.isLoaded ? (
        <div>{"Loaded"}</div>
      ): (
        <div>{"Not Loaded"}</div>
      );
    };
    
    const mapStateToProps = (state) => ({
      isLoaded: state.isLoaded,
    });
    
    const mapDispatchToProps = { fetchData };
    
    export default connect(mapStateToProps, mapDispatchToProps)(App);
    

    فهرست

  8. چطوری از متد connect از پکیج react-redux استفاده می‌کنیم؟

    برای دسترسی به دیتای نگهداری شده توی ریداکس باید دو گام زیر رو طی کنیم:

    1. از متد mapStateToProps استفاده می‌کنیم و متغیرهای state که از store می‌خواییم لود کنیم رو مشخص می‌کنیم.

    2. با استفاده از متد connect دیتا رو به props میدیم، چون دیتایی که این HOC میاره به عنوان props به کامپوننت داده میشه. متد connect رو هم از پکیج react-redux باید بارگذاری کنیم.

    import React from 'react';
    import { connect } from 'react-redux';
    
    const App = props => {
      render() {
        return <div>{props.containerData}</div>
      }
    };
    
    const mapStateToProps = state => {
      return { containerData: state.data }
    };
    
    export default connect(mapStateToProps)(App);
    

    فهرست

  9. چطوری میشه state ریداکس رو ریست کرد؟

    لازمه که توی برنامه یه root reducer تعریف کنیم که وظیفه معرفی ریدیوسرهای ایجاد شده با combineReducers را دارد.

    مثلا بیایین rootReducer رو برای‌ ست کردن state اولیه با فراخوانی عمل USER_LOGOUT تنظیم کنیم. همونطوری که می‌دونیم، به صورت پیش‌فرض ما بنا رو براین میزاریم که reducerها با اجرای مقدار undefined به عنوان پارامتر اول initialState رو برمی‌گردونن و حتی actionش هم مهم نیست.

    const appReducer = combineReducers({
      /* your app's top-level reducers */
    });
    
    const rootReducer = (state, action) => {
      if (action.type === "USER_LOGOUT") {
        state = undefined;
      }
    
      return appReducer(state, action);
    };
    

    اگه از پکیج redux-persist استفاده می‌کنین، احتمالا لازمه که storage رو هم خالی کنین. redux-persist یه کپی از دیتای موجود در store رو توی localstorage نگهداری می‌کنه. اولش، لازمه که یه موتور مناسب برای storage بارگذاری کنیم که برای تجزیه state قبل مقداردهی اون با undefined و پاک کردن مقدارشون مورد استفاده قرار می‌گیره.

    const appReducer = combineReducers({
      /* your app's top-level reducers */
    });
    
    const rootReducer = (state, action) => {
      if (action.type === "USER_LOGOUT") {
        Object.keys(state).forEach((key) => {
          storage.removeItem(`persist:${key}`);
        });
    
        state = undefined;
      }
    
      return appReducer(state, action);
    };
    

    فهرست

  10. هدف از کاراکتر @ توی decorator متد connect چیه؟

    کاراکتر(symbol) @ در حقیقت یه نماد از جاواسکریپت برای مشخص کردن decoratorهاست. _Decorator_ها این امکان رو بهمون میده که بتونیم برای کلاس و ویژگی‌های(properties) اون یادداشت‌ها و مدیریت‌کننده‌هایی رو توی زمان طراحی اضافه کنیم.

    بزارین یه مثال رو برای Redux بزنیم که یه بار از decorator استفاده کنیم و یه بار بدون اون انجامش بدیم.

    • بدون decorator:

    import React from "react";
    import * as actionCreators from "./actionCreators";
    import { bindActionCreators } from "redux";
    import { connect } from "react-redux";
    
    function mapStateToProps(state) {
      return { todos: state.todos };
    }
    
    function mapDispatchToProps(dispatch) {
      return { actions: bindActionCreators(actionCreators, dispatch) };
    }
    
    class MyApp extends React.Component {
      //...define your main app here
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(MyApp);
    
    • با decorator:

    import React from "react";
    import * as actionCreators from "./actionCreators";
    import { bindActionCreators } from "redux";
    import { connect } from "react-redux";
    
    function mapStateToProps(state) {
      return { todos: state.todos };
    }
    
    function mapDispatchToProps(dispatch) {
      return { actions: bindActionCreators(actionCreators, dispatch) };
    }
    
    @connect(mapStateToProps, mapDispatchToProps)
    export default class MyApp extends React.Component {
      //...define your main app here
    }
    

    مثال‌های بالا تقریبا شبیه به هم هستن فقط یکیشون از decoratorها استفاده می‌کنه و اون یکی حالت عادیه. سینتکس decorator هنوز به صورت پیش‌فرض توی هیچ‌کدوم از runtime‌های جاواسکریپت فعلا وجود نداره و هنوز به شکل آزمایشی مورد استفاده قرار می‌گیره ولی پروپوزال افزوده شدنش به زبان در دست بررسیه. خوشبختانه فعلا می‌تونیم از babel برای استفاده از اون استفاده کنیم.

    فهرست

  11. تفاوت‌های context و React Redux چیه؟

    می‌تونیم از Context برای استفاده از state توی مراحل داخلی کامپوننت‌های nested استفاده کنیم و پارامترهای مورد نظرمون رو تا هر عمقی که دلخواه‌مون هست ببریم و استفاده کنیم، که البته context برای همین امر به وجود اومده. این درحالیه که Redux خیلی قدرتمندتره، پلاگین‌های مختلفی داره و یه سری‌ قابلیت‌های حرفه‌ای‌تری رو بهمون میده. بعلاوه، خود React Redux به شکل داخلی از context استفاده می‌کنه ولی به شکل عمومی این موضوع دیده نمیشه.

    فهرست

  12. چرا به توابع state ریداکس reducer میگن؟

    Reducerها همیشه یه مجموعه از stateها رو جمع‌آوری و تحویل میدن(براساس همه actionهای قبلی). برای همین، اونا به عنوان یه سری کاهنده‌های state عمل می‌کنن. هر وقت یه reducer از Redux فراخوانی میشه، state و action به عنوان پارامتر پاس داده میشن و بعدش این state بر اساس actionجاری مقادیرش کاهش یا افزایش داده می‌شوند و بعدش state بعدی برگشت داده میشه. یعنی شما می‌تونین یه مجموعه از داده‌ها رو reduce کنین و به state نهایی که دلخواهتون هست برسین.

    فهرست

  13. توی redux چطوری میشه api request زد؟

    میشه از middleware(میااان‌افزااار) redux-thunk استفاده کرد که اجازه میده بتونیم action‌های async داشته باشیم.

    بزارین یه مثال از دریافت اطلاعات یه حساب خاص با استفاده از فراخوانی AJAX با استفاده از fetch API بزنیم:

    export function fetchAccount(id) {
      return (dispatch) => {
        dispatch(setLoadingAccountState()); // Show a loading spinner
        fetch(`/account/${id}`, (response) => {
          dispatch(doneFetchingAccount()); // Hide loading spinner
          if (response.status === 200) {
            dispatch(setAccount(response.json)); // Use a normal function to set the received state
          } else {
            dispatch(someError);
          }
        });
      };
    }
    
    function setAccount(data) {
      return { type: "SET_Account", data: data };
    }
    

    فهرست

  14. آیا لازمه همه state همه کامپوننت‌هامونو توی ریداکس نگهداری کنیم؟

    نه لزومی نداره، دیتاهای عمومی برنامه رو میشه توی store ریداکس نگهداری کرد و مسائل مربوط به UI به شکل داخلی توی state کامپوننت‌ها نگهداری بشن.

    فهرست

  15. روش صحیح برای دسترسی به store ریداکس چیه؟

    بهترین روش، بسته به هر پروژه و هر فرد می‌تونه متفاوت باشه، ترجیح من استفاده از هوک‌های useSelector و useDispatch هستن، برای دسترسی به store و انجام عملیات روی اون استفاده از تابع connect هم می‌تونیم استفاده کنیم که یه کامپوننت جدید ایجاد‌ می‌کنه که کامپوننت جاری توی اون قرار داره و دیتای لازم رو بهش پاس میده. این پترن با عنوان Higher-Order Components یا کامپوننت‌های مرتبه بالاتر شناخته میشه و یه روش مورد استفاده برای extend کردن کارکرد کامپوننت‌های ری‌اکتی محسوب میشه. این تابع بهمون این امکان رو میده که state و actionهای مورد نظرمون رو به داخل کامپوننت بیاریم و البته به شکل پیوسته با تغییرات اونا کامپوننت‌مون رو به روز کنیم.

    بیایین یه مثال از کامپوننت <FilterLink> با استفاده از تابع connect بزنیم:

    import { connect } from "react-redux";
    import { setVisibilityFilter } from "../actions";
    import Link from "../components/Link";
    
    const mapStateToProps = (state, ownProps) => ({
      active: ownProps.filter === state.visibilityFilter,
    });
    
    const mapDispatchToProps = (dispatch, ownProps) => ({
      onClick: () => dispatch(setVisibilityFilter(ownProps.filter)),
    });
    
    const FilterLink = connect(mapStateToProps, mapDispatchToProps)(Link);
    
    export default FilterLink;
    

    فهرست

  16. تفاوت‌های component و container توی ریداکس چی هست؟

    • Component یه کامپوننت class یا function هست که لایه ظاهری و مربوط به UI برنامه‌مون توی اون قرار می‌گیره.

    • Container یه اصطلاح غیررسمی برای کامپوننت‌هایی‌ـه که به store ریداکس وصل شدن. Containerها به state subscribe می‌کنن یا actionها رو dispatch می‌کنن و هیچ DOM elementای رو رندر نمی‌کنن بلکه کامپوننت‌های UI رو به عنوان child به روز می‌کنن.

    نکته مهم: استفاده از این روش تقریبا توی سال ۲۰۱۹ دیگه منقضی محسوب میشه و چون هوک‌های ری‌اکت خیلی راحت می‌تونن دیتا رو توی هر سطح از کامپوننت برامون لود کنن، پس جدا نشدن این دولایه تاثیر چشم‌گیری توی ساده بودن کدها نخواهد داشت و بعضا حتی می‌تونه کار رو سخت‌تر کنه، پس به عنوان مترجم توصیه می‌کنم این کار رو انجام ندین:)

    فهرست

  17. هدف از constantها تا typeها توی ریداکس چیه؟

    Constantها یا موارد ثابت بهتون این اجازه رو میدن که کارکرد یه عملکرد مشخص رو به سادگی توی پروژه پیدا کنید. البته از خطاهای ساده‌ای که ممکنه براتون پیش بیاد هم جلوگیری می‌کنه. مثل خطاهای مربوط به type یا ReferenceErrorها که ممکنه خیلی راحت رخ بدن.

    اکثرا مقادیر ثابت constant رو توی یه فایل مثل (constants.js یا actionTypes.js) قرار می‌دیم.

    export const ADD_TODO = "ADD_TODO";
    export const DELETE_TODO = "DELETE_TODO";
    export const EDIT_TODO = "EDIT_TODO";
    export const COMPLETE_TODO = "COMPLETE_TODO";
    export const COMPLETE_ALL = "COMPLETE_ALL";
    export const CLEAR_COMPLETED = "CLEAR_COMPLETED";
    

    توی ریداکس از این مقادیر دوتا جا استفاده میشه:

    1. موقع ساخت action:

      مثلا فرض می‌کنیم actions.js:

    import { ADD_TODO } from "./actionTypes";
    
    export function addTodo(text) {
      return { type: ADD_TODO, text };
    }
    
    1. توی reducerها:

      مثلا یه فایل به اسم reducer.js رو در نظر بگیرین:

    import { ADD_TODO } from "./actionTypes";
    
    export default (state = [], action) => {
      switch (action.type) {
        case ADD_TODO:
          return [
           ...state,
            {
              text: action.text,
              completed: false,
            },
          ];
        default:
          return state;
      }
    };
    

    فهرست

  18. روش‌های مختلف برای نوشتن mapDispatchToProps چیه؟

    چندین روش برای bind کردن action به متد dispatch توی mapDispatchToProps هستش که پایین بررسی‌شون می‌کنیم:

    const mapDispatchToProps = (dispatch) => ({
      action: () => dispatch(action()),
    });
    
    export default connect(mapStateToProps, mapDispatchToProps)(App);
    
    const mapDispatchToProps = (dispatch) => ({
      action: bindActionCreators(action, dispatch),
    });
    
    export default connect(mapStateToProps, mapDispatchToProps)(App);
    
    const mapDispatchToProps = { action };
    
    export default connect(mapStateToProps, mapDispatchToProps)(App);
    

    روش سوم خلاصه شده روش اوله که معمولا توصیه میشه.

    فهرست

  19. کاربرد پارامتر ownProps توی mapStateToProps و mapDispatchToProps چیه؟

    اگه پارامتر ownProps ارائه شده باشه، ReactRedux پارامترهایی که به کامپوننت پاس داده شدن رو به تابع connect پاس میده. پس اگه یه کامپوننت connect شده مثل کد زیر داشته باشین:

    import ConnectedComponent from "./containers/ConnectedComponent";
    
    <ConnectedComponent user={"john"} />;
    

    پارامتر ownProps توی mapStateToProps و mapDispatchToProps یه object رو خواهد داشت که مقدار زیر رو داره:

    {
      user: "john";
    }
    

    می‌تونیم از این مقدار استفاده کنیم تا در مورد مقدار بازگشتی تصمیم بگیریم.

    فهرست

  20. ساختار پوشه‌بندی ریشه ریداکس اکثرا چطوریه؟

    اکثر برنامه‌های ریداکسی یه ساختاری مثل این دارند:

    1. Components: که برای کامپوننت‌های dumb یا فقط نمایشی که به ریداکس وصل نیستند استفاده می‌شود.

    2. Containers: که برای کامپوننت‌های smart که به ریداکس وصل هستن.

    3. Actions: که برای همه actionها استفاده میشه و هر فایل به بخشی از عملکرد برنامه تعلق داره.

    4. Reducers: که برای همه reducerها استفاده میشه و هر فایل به یه state توی store تعلق داره.

    5. Store: که برای ساختن store استفاده میشه.

    این ساختار برای یه برنامه کوچک تا بزرگ کاربرد داره. البته اون بخشی ازش که کامپوننت‌های dumb و smart یا همون container و component رو بر طبق وصل شدنشون به ریداکس جدا می‌کردیم تقریبا منقصی محسوب میشه.

    فهرست

  21. redux-saga جیه؟

    redux-saga یه کتابخونه هست که تمرکز اصلیش برای ایجاد side-effectهاست (چیزهای asynchronous مثل fetch کردن داده و غیرشفاف مثل دسترسی به کش مرورگر) که توی برنامه‌های React/Redux با این روش ساده‌تر و بهتر انجام میشه.

    پکیج ریداکس ساگا روی NPM هست:

    $ npm install --save redux-saga
    

    فهرست


  1. مدل ذهنی redux-saga چطوریه؟

    Saga مثل یه thread جداگانه برای برنامه عمل می‌کنه و فقط برای مدیریت ساید افکت کارایی داره. redux-saga یه میان‌افزار(middlewaer) برای ریداکس‌ـه، که به معنی اینه که می‌تونه به صورت اتوماتیک توسط actionهای ریداکس شروع بشه، متوقف بشه و یا کار خاصی انجام بده. این میان‌افزار به کل store ریداکس و actionهایی که کار می‌کنن دسترسی داره و می‌تونه هر action دیگه‌ای رو dispatch کنه.

    فهرست

  2. تفاوت افکت‌های call و put توی redux-saga چی هست؟

    هر دوی افکت‌های call و put سازنده‌های افکت هستن. تابع call برای ایجاد توضیح افکت استفاده میشه که به میان‌افزار دستور میده منتظر call بمونه. تابع put یه افکت ایجاد می‌کنه، که به store میگه یه action خاص رو فقط اجرا کنه.

    بزارین یه مثال در مورد عملکرد این دوتا افکت برای دریافت داده یه کاربر بزنیم.

    function* fetchUserSaga(action) {
      // `call` function accepts rest arguments, which will be passed to `api.fetchUser` function.
      // Instructing middleware to call promise, it resolved value will be assigned to `userData` variable
      const userData = yield call(api.fetchUser, action.userId);
    
      // Instructing middleware to dispatch corresponding action.
      yield put({
        type: "FETCH_USER_SUCCESS",
        userData,
      });
    }
    

    فهرست

  3. Redux Thunk چیه؟

    میان افزار Redux Thunk بهمون این اجازه رو میده که actionهایی رو بسازیم که به‌جای action عادی تابع‌ برگردونن thunk می‌تونه به عنوان یه ایجاد کننده delay برای dispatch کردن یه action استفاده کنیم، یا حتی با بررسی یه شرط خاص یه action رو dispatch کنیم. تابعی که توی action استفاده میشه و dispatch و getState رو به عنوان پارامتر ورودی می‌گیره.

    فهرست

  4. تفاوت‌های redux-saga و redux-thunk چیا هستن؟

    هر دوی ReduxThunk و ReduxSaga می‌تونن مدیریت ساید افکت‌ها رو به دست بگیرن. توی اکثر سناریوها، Thunk از Promise استفاده می‌کنه، درحالیکه Saga از Generatorها استفاده‌می‌کنه. Thunk تقریبا ساده‌تره و promise رو تقریبا همه دولوپرها باهاش آشنا هستن، در حالی‌که Sagas/Generatorها خیلی قوی‌تر هستن و می‌تونن کاربردی‌تر باشن ولی خب لازمه که یاد بگیرینش. هردوی میان‌افزارها می‌تونن خیلی مفید باشن و شما می‌تونین با Thunks شروع کنین و اگه جایی دیدین نیازمندی‌تون رو برآورده نمی‌کنه سراغ Sagas برید.

    فهرست

  5. Redux DevTools چیه؟

    ReduxDevTools یه محیط برای مشاهده در لحظه تغییرات ریداکس فراهم می‌کنه و قابلیت اجرای مجدد action و یه رابط‌ کاربری قابل شخصی‌سازی رو فراهم می‌کنه. اگه نمی‌خوایین پکیج ReduxDevTools رو نصب کنید می‌تونین از افزونه ReduxDevTools برای Chrome و Firefox استفاده کنین.

    فهرست

  6. ویژگی‌های Redux DevTools کدوما هستن؟

    1. بهتون اجازه میده که اطلاعات هر state و payload پاس داده شده به action رو مشاهده کنین.

    2. بهتون اجازه میده که actionهای اجرا شده رو لغو کنید.

    3. اگه یه تغییری روی کدهای reducer بدین، هر actionای که stage شده رو مجدد ارزیابی می‌کنه.

    4. اگه یه reducers یه خطایی بده، میشه متوجه شد که در طی انجام شدن کدوم action این اتفاق افتاده و خطا چی بوده.

    5. با persistState می‌تونین دیباگ روی موقع reloadهای مختلف ذخیره کنید.

    فهرست



  1. سلکتورهای ریداکس چی هستن و چرا باید ازشون استفاده کنیم؟

    Selectorها یه سری تابع هستن که state ریداکس رو به عنوان یه پارامتر دریافت می‌کنه و یه بخش از اون state که میخواییم رو برگشت میده.

    برای مثال، دریافت اطلاعات کاربر از ریداکس با یه selector مث این می‌تونه فراهم شده باشه:

    const getUserData = (state) => state.user.data;
    

    فهرست

  2. Redux Form چیه؟

    ReduxForm در کنار ری‌اکت و ریداکس کار می‌کنه تا اطلاعات فرم‌ها رو توی state ریداکس مدیریت کنیم. ReduxForm می‌تونه با inputهای خام HTML5 هم کار کنه، ولی با فریم‌ورک‌های معروف UI مثل Material، ReactWidgets و ReactBootstrap کار کنه.

    فهرست

  3. اصلی‌ترین ویژگی‌های Redux Form چیه؟

    1. ماندگاری مقادیر فیلدهای فرم توی ریداکس.

    2. اعتبارسنجی (sync/async) و ثبت فرم.

    3. فرمت کردن، تجزینه و نرمالسازی مقادیر فیلدها.

    فهرست

  4. چطوری میشه چندتا middleware به ریداکس اضافه کرد؟

    می‌تونیم از applyMiddleware استفاده کنیم.

    برای مثال میشه از redux-thunk و logger به عنوان پارامترهای applyMiddleware استفاده کنیم:

    import { createStore, applyMiddleware } from "redux";
    const createStoreWithMiddleware = applyMiddleware(
      ReduxThunk,
      logger
    )(createStore);
    

    فهرست

  5. چطوری میشه توی ریداکس initial state تعریف کرد؟

    لازم داریم که state اولیه رو به عنوان پارامتر دوم به createStore پاس بدیم:

    const rootReducer = combineReducers({
      todos: todos,
      visibilityFilter: visibilityFilter,
    });
    
    const initialState = {
      todos: [{ id: 123, name: "example", completed: false }],
    };
    
    const store = createStore(rootReducer, initialState);
    

    فهرست

  6. تفاوت‌های Relay با Redux کدوما هستن؟

    Relay و Redux توی این مورد که دوتاشونم از یه store استفاده می‌کنن شبیه بهم هستن. تفاوت اصلی این دو اینه که relay فقط stateهایی رو مدیریت می‌کنه که از سرور تاثیر گرفتن و همه دسترسی‌هایی که به state مربوطه رو با کوئری‌های GraphQL(برای خوندن داده‌ها) و mutationها (برای تغییرات داده) انجام میده. Relay داده‌ها برای شما رو cache می‌کنه و گرفتن داده از سرور رو برای شما بهینه می‌کنه. چون فقط تغییرات رو دریافت میکرد و نه چیز دیگه‌ای.




React Native


  1. تفاوت‌های React Native و React کدوما هستن؟

    • React یه کتابخونه جاواسکریپتی هست که از اجرای اون روی frontend و اجرای اون روی سرور برای تولید رابط کاربری و برنامه‌های تحت وب پشتیبانی می‌کنه.

    • React Native یه فریم‌ورک موبایل هست که کدها رو به کامپوننت‌های native روی موبایل compile می‌کنه و بهمون این اجازه رو میده که برنامه‌های موبایلی(iOS, Android, and Windows) رو با استفاده از جاواسکریپت بسازیم که از ری‌اکت برای تولید کامپوننت استفاده می‌کنه.

    فهرست

  2. چطوری میشه برنامه React Native رو تست کرد؟

    ReactNative می‌تونه توی شبیه‌سازهای سیستم‌عامل‌های موبایلی مثل iOS و Android تست کرد. می‌تونیم برنامه‌های خودمون رو توی برنامه expo(https://expo.io) توی گوشی خودمون هم ببینیم که با استفاده از QR-code می‌تونه یه برنامه روی کامپیوتر و گوشی sync کنه، البته باید هر دوی این دستگاه‌ها تو یه شبکه وایرلس باشه.

    فهرست

  3. چطوری میشه توی React Native لاگ کرد؟

    می‌تونیم از console.log، console.warn و غیره استفاده کرد. از نسخه ReactNative 0.29 می‌تونیم خیلی ساده کدهای زیر رو اجرا کنیم که لاگ رو توی خروجی ببینیم:

    $ react-native log-ios
    $ react-native log-android
    

    فهرست

  4. چطوری میشه React Native رو دیباگ کرد؟

    برای دیباگ کردن برنامه ری‌اکت native گام‌های زیر رو طی می‌کنیم:

    1. برنامه رو توی شبیه‌ساز iOS اجرا می‌کنیم.

    2. دکمه‌های Command + D رو فشار میدیم و یه صفحه وب توی آدرس http://localhost:8081/debugger-ui اجرا میشه.

    3. چک‌باکس On Caught Exceptions_ رو برای یه دیباگ بهتر فعال می‌کنیم.

    4. دکمه‌های Command + Option + I رو برای اجرای developer-tools کروم فشار میدیم یا از طریق منوهای View و Developer و DeveloperTools باز می‌کنیم‌ـش.

    5. حالا می‌تونیم برنامه مورد نظر خودمون رو به راحتی تست کنیم.


کتابخونه‌های ری‌اکت و Integrationهاشون


  1. کتابخونه reselect چیه و چطوری کار می‌کنه؟

    Reselect یه کتابخونه کمکی برای selectorهای ریداکس‌ـه که از مفهوم memoization استفاده می‌کنه. این کتابخونه به شکلی نوشته شده بوده که داده‌های هر برنامه Redux-like یا شبیه ریداکس رو پردازش کنه، ولی نتونسته با هیچ برنامه یا کتابخونه دیگه‌ای گره بخوره.

    Reselect یه کپی از آخرین inputs/outputs از هر فراخوانی رو نگهداری می‌کنه و فقط زمانی اونو دوباره محاسبه می‌کنه که تغییراتی توی ورودی رخ داده باشه. اگه همون ورودی‌ها دوبار استفاده بشن، Reselect مقدار cache شده رو برمی‌گردونه. memoization و cacheای که استفاده میشه تا حد زیادی قابل شخصی سازیه.

    فهرست

  2. Flow چیه؟

    Flow یه static type checker هستش که طراحی شده تا خطاهای مربوط به نوع داده‌ها رو توی جاواسکریپت پیدا کنیم. نوع‌های flow می‌تونه خیلی ریزبینانه‌تر از رویکردهای سنتی بررسی نوع عمل کنه. برای مثال، Flow بهمون کمک‌ می‌کنه که خطاهای مربوط به دریافت null توی برنامه رو کنترل کنیم که توی روش‌های سنتی غیرممکنه تقریبا.

    فهرست

  3. تفاوت‌های Flow و PropTypes کدوما هستن؟

    Flow یه ابزار تجزیه و تحلیل استاتیک(static-checker) هستش که از یه سری ویژگی‌های بیشتر از زبان جاواسکریپت رو پشتیبانی می‌کنه و بهمون کمک‌ می‌کنه که در بخش‌های مختلف برنامه نوع داده‌ها رو اضافه کنیم و خطاهایی که مرتبط با بررسی نوع‌ها هست رو موقع compile ازشون جلوگیری کنیم. PropTypeها یه روش بررسی نوع داده ورودی کامپوننت‌های ساده (موقع runtime) هست که روی ری‌اکت اضافه شدن. PropType به غیر از نوع داده‌‌هایی که به کامپوننت موردنظر به عنوان prop داده شده رو نمی‌تونه بررسی کنه. پس اگه دنبال یه روش برای بررسی نوع داده به شکل منعطف هستیم که توی کل پروژه عمل کنه Flow یا TypeScript روش‌های بهتری هستن.

    فهرست

  4. چطوری از آیکون‌های font-awesome توی ری‌اکت استفاده کنیم؟

    به شکل کلی، باید css و فونت آیکون مربوط به font-awesome به پروژه اضافه بشه، می‌تونیم از پکیج این کتابخونه روی npm استفاده کنیم و بگیم که باید گام‌های زیر برای استفاده از font-awesome توی ری‌اکت باید طی بشه:

    1. پکیج font-awesome رو نصب می‌کنیم:

    npm install --save font-awesome
    
    1. font-awesome رو توی فایل index.js بارگذاری می‌کنیم:

    import "font-awesome/css/font-awesome.min.css";
    
    1. از کلاس این فونت توی classNameهای موردنظر استفاده می‌کنیم:

    render() {
      return <div><i className={'fa fa-spinner'} /></div>
    }
    

    فهرست

  5. React Dev Tools چیه؟

    ReactDeveloperTools بهمون اجازه اینو میده که سلسله مراتب کامپوننت‌های برنامه رو بررسی کنیم که شامل prop و state هم میشه. این مورد به دو روش افزونه (برای Chrome و Firefox) و یه برنامه جانبی مستقل (که با سافاری و مرورگرهای دیگه هم کار می‌کنه) در دسترسه.

    پس سه مورد رو می‌تونیم در نظر بگیریم:

    1. افزونه Chrome

    2. افزونه Firefox

    3. برنامه مستقل (Safari ،ReactNative و...)

    فهرست

  6. چرا توی کروم devtools برای فایل‌های local لود نمیشه؟

    اگه یه فایل محلی HTML رو توی مرورگر باز کنیم (file://...) بعدش لازمه که ChromeExtensions یا همون افزونه‌های کروم رو باز کنیم و چک‌‌باکس Allow access to file URLs رو فعال کنیم.

    فهرست

  7. چطوری از Polymer توی React استفاده کنیم؟

    1. یه element برای Polymer ایجاد می‌کنیم:

    <link rel="import" href="../../bower_components/polymer/polymer.html" />;
    Polymer({
      is: "calender-element",
      ready: function () {
        this.textContent = "I am a calender";
      },
    });
    
    1. کامپوننت Polymer رو با تگ‌های HTML ایجاد می‌کنیم و توی داکیومنت html بارگذاری می‌کنیم، برای مثال اونو توی index.html برنامه بارگذاری کنیم:

    <link
      rel="import"
      href="./src/polymer-components/calender-element.html"
    />
    
    1. از اون element توی فایل JSX استفاده می‌کنیم:

    import React from "react";
    
    class MyComponent extends React.Component {
      render() {
        return <calender-element />;
      }
    }
    
    export default MyComponent;
    

    فهرست

  8. مزایای React نسبت به Vue.js کدوما هستن؟

    ری‌اکت مزایای زیر رو نسبت به Vue.js داره:

    1. انعطاف پذیری بیشتری رو توی توسعه برنامه‌های بزرگ بهمون میده.

    2. تست کردنش راحت‌تره.

    3. برای تولید برنامه‌های موبایلی هم مناسبه.

    4. اطلاعات و راهکارهای مختلفی براش توی دسترسه.

    نکته: لیست موارد فوق صرفاً اظهار نظر شخصی بوده و براساس تجربه حرفه‌ای ممکن است متفاوت باشد. اما به عنوان پارامترهای پایه مفید هستن

    فهرست

  9. تفاوت‌های React و Angular کدوما هستن؟

    React Angular
    ری‌اکت یه کتابخونه‌ست و فقط یه لایه view داره Angular یه فریم ورکه و عملکردش کاملا MVC هستش
    در ری‌اکت جریان داده‌ها فقط از یه طریق(one-directional) هستش و به همین خاطر اشکال زدایی(debug) راحت تره در Angular جریان داده‌ها از دو جهته، یعنی اتصال داده‌های دوطرفه بین والدین و فرزندان رو داره و به خاطر همین اشکال زدایی سخت تره

    نکته: لیست موارد فوق صرفاً اظهار نظر شخصی بوده و براساس تجربه حرفه‌ای ممکن است متفاوت باشد. اما به عنوان پارامترهای پایه مفید هستند.
    فهرست

  10. چرا تب React در DevTools نشان داده نمی‌شود؟

    موقع لود صفحه، React DevTools یه گلوبال به اسم __REACT_DEVTOOLS_GLOBAL_HOOK__ تنظیم میکنه، بعدش ری‌اکت موقع مقداردهی اولیه با اون هوک ارتباط برقرار میکنه. اگه وب سایت از ری‌اکت استفاده نکنه یا ری‌اکت نتونه با DevTools ارتباط برقرار کنه اون تب رو نشون نمیده.

    فهرست

  11. Styled components چیه؟

    styled-components یه کتابخونه جاواسکریپت‌ـه برای طراحی ظاهر برنامه‌های ری‌اکت، پیچیدگی بین استایل‌ها و کامپوننت‌ها رو حذف میکنه و بهمون این امکان رو میده که کامپوننت‌هایی رو تولید کنیم که نگران استایل‌شون نیستیم و خیال‌مون راحته که استایل‌شون کنار خودشون منتقل میشن و css واقعی رو با جاواسکریپت بنویسیم.

    فهرست

  12. یه مثال از Styled Components می‌تونی بگی؟

    بیاین کامپوننت‌های <Title> و <Wrapper> رو با استایل‌های خاص برای هر کدوم بسازیم.

    import React from 'react'
    import styled from 'styled-components'
    
    // Create a <Title> component that renders an <h1> which is centered, red and sized at 1.5em
    const Title = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: palevioletred;
    `
    
    // Create a <Wrapper> component that renders a <section> with some padding and a papayawhip background
    const Wrapper = styled.section`
      padding: 4em;
      background: papayawhip;
    `
    

    این دو تا متغیر، Title و Wrapper، کامپوننت‌هایی هستن که می‌تونیم مثل هر کامپوننت دیگه ای رندرشون کنیم.


    <Wrapper>
      <Title>Lets start first styled component!</Title>
    </Wrapper>
    

    فهرست


  1. Relay چیه؟

    Relay یه فریم ورک جاواسکریپت‌‌ـه که برای ارائه یک لایه داده و ارتباط client-server به برنامه‌های وب با استفاده از لایه view ری‌اکت استفاده میشه.

    فهرست

  2. چطوری میشه از تایپ اسکریپت توی create-react-app استفاده کرد؟

    از نسخه react-scripts@2.1.0 به بالاتر، پشتیبانی به شکل داخلی برای typescript وجود داره. میتونیم پارامتر --typescript رو به صورت زیر به این اسکریپت پاس بدیم:

    npx create-react-app my-app --typescript
    
    # or
    
    yarn create react-app my-app --typescript
    

    ولی برای ورژن‌های پایین‌تر وقتی داریم یه پروژه جدید می سازیم react scripts، گزینه --scripts-version رو به عنوان react-scripts-ts تنظیم می‌کنیم. react-scripts-ts مجموعه ای از تنظیمات برای گرفتن پروژه create-react-app و آوردن typeScript داخلش هست.

    حالا ساختار پروژه باید این شکلی باشه:

    my-app/
    ├─.gitignore
    ├─ images.d.ts
    ├─ node_modules/
    ├─ public/
    ├─ src/
    │  └─...
    ├─ package.json
    ├─ tsconfig.json
    ├─ tsconfig.prod.json
    ├─ tsconfig.test.json
    └─ tslint.json
    

    فهرست



مطالب متفرقه



  1. اصلی‌ترین ویژگی‌های کتابخونه reselect کدوما هستن؟

    1. Selector‌ها داده‌های مشتق شده رو محاسبه میکنه و به ریداکس اجازه میدن حداقل state‌های ممکن رو ذخیره کنه.

    2. Selector‌‌ها memoize شده هستن و یه selector تا وقتی که یکی از آرگومان‌هاش تغییر نکرده معتبر نیست.

    3. Selector‌ها قابل ترکیب هستن یعنی می‌تونن به عنوان ورودی برای بقیه Selector‌ها استفاده بشن.

    فهرست

  2. یه مثال از کارکرد کتابخونه reselect بزن؟

    بیاین محاسبات و مقادیر مختلف یه سفارش حمل و نقل رو با استفاده ساده از Reselect انجام بدیم:

    import { createSelector } from 'reselect'
    
    const shopItemsSelector = state => state.shop.items
    const taxPercentSelector = state => state.shop.taxPercent
    
    const subtotalSelector = createSelector(
      shopItemsSelector,
      items => items.reduce((acc, item) => acc + item.value, 0)
    )
    
    const taxSelector = createSelector(
      subtotalSelector,
      taxPercentSelector,
      (subtotal, taxPercent) => subtotal * (taxPercent / 100)
    );
    
    export const totalSelector = createSelector(
      subtotalSelector,
      taxSelector,
      (subtotal, tax) => ({ total: subtotal + tax })
    )
    
    let exampleState = {
      shop: {
        taxPercent: 8,
        items: [
          { name: 'apple', value: 1.20 },
          { name: 'orange', value: 0.95 },
        ]
      }
    }
    
    console.log(subtotalSelector(exampleState)) // 2.15
    console.log(taxSelector(exampleState))      // 0.172
    console.log(totalSelector(exampleState))    // { total: 2.322 }
    

    فهرست

  3. توی Redux اکشن چیکار می‌کنه؟

    اکشن‌ها آبجکت‌های ساده جاواسکریپت یا اطلاعاتی هستن که داده‌ها رو از برنامه به store میفرستن. اونا تنها منابع اطلاعاتی برای store هستن. اکشن باید یه ویژگی type داشته باشه که نوع اکشن‌ای که انجام میشه رو نشون بده.

    برای مثال اکشن‌ای که نشون میده یه آیتم todo جدید اضافه شده، می‌تونه این شکلی باشه:

    {
      type: 'ADD_TODO',
      text: 'Add todo item'
    }
    

    البته یه استانداردی هست که برای داده‌ای که می‌خواییم منتقل کنیم اسم متغیر انتخاب نکنیم و از ویژگی payload براش استفاده کنیم، مثال فوق با این استاندارد به شکل زیر می‌تونه پیاده‌سازی بشه:

    {
      type: 'ADD_TODO',
      payload: 'Add todo item'
    }
    

    فهرست

  4. استاتیک شی با کلاس‌های ES6 در React کار می کنه؟

    خیر، استاتیک‌ها فقط با React.createClass کار می‌کنن:

    someComponent= React.createClass({
      statics: {
        someMethod: function() {
          //..
        }
      }
    })
    

    اما میتونیم استاتیک‌ها رو داخل کلاس‌های ES6 یا خارج از کلاس مثل زیر بنویسیم،

    class Component extends React.Component {
      static propTypes = {
        //...
      }
    
      static someMethod() {
        //...
      }
    }
    
    class Component extends React.Component {
      ....
    }
    
    Component.propTypes = {...}
    Component.someMethod = function(){....}
    

    فهرست

  5. ریداکس رو فقط با ری‌اکت میشه استفاده کرد؟

    ریداکس می‌تونه به عنوان یه محل برای ذخیره داده برای لایه UI استفاده بشه. رایج ترین کاربرد ریداکس برای ری‌اکت و ری‌اکت نیتیو هستش، ولی یه سری کارهایی هم برای هماهنگ کردنش با Angular، Angular 2، Vue، Mithril و موارد دیگه موجوده. ریداکس به راحتی یه مکانیسم اشتراکی ارائه میده که می‌تونه برای کد‌های دیگه هم استفاده بشه.

    فهرست

  6. برای استفاده از Redux به ابزار build خاصی احتیاج داریم؟

    ریداکس در اصل توی ES6‌ نوشته شده و برای build روی ES5 با Webpack و Babel کار کردن، در حقیقت ما باید بتونیم بدون توجه به مراحل و نسخه جاواسکریپت ازش استفاده کنیم. ریداکس همینطور یه ساختار UMD ارائه میده که می‌تونه مستقیم و بدون هیچگونه وابستگی به شکل مستقیم روی مرورگر مورد استفاده قرار بگیره.

    فهرست

  7. مقادیر پیش‌فرض ریداکس فرم چطوری تغییرات رو از state می‌گیرن؟

    باید تنظیمات enableReinitialize: true رو اضافه کنیم.

    const InitializeFromStateForm = reduxForm({
      form: 'initializeFromState',
      enableReinitialize: true
    })(UserEdit)
    

    اگه prop ‍‍initialValues به روز بشه، فرم‌مون هم به روز میشه.

    فهرست

  8. توی PropTypeهای ری‌اکت چطوری میشه برای یه prop چند نوع داده مجاز مشخص کرد؟

    می‌تونیم از یکی از متد‌های PropTypes به اسم oneOfType استفاده کنیم.

    برای مثال، ویژگی height رو می‌تونیم با دو نوع string یا number مثل زیر تعریف کنیم:

    Component.PropTypes = {
      size: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.number
      ])
    }
    

    فهرست

  9. می‌تونیم فایل svg رو به عنوان کامپوننت import کنیم؟

    میتونیم SVG‌ رو مستقیما به عنوان یه کامپوننت به جای لود کردنش به عنوان یه فایل ایمپورت کنیم. این ویژگی توی react-scripts@2.0.0 و ورژن‌های بالاتر در دسترسه.

    import { ReactComponent as Logo } from './logo.svg'
    
    const App = () => (
      <div>
        {/* Logo is an actual react component */}
        <Logo />
      </div>
    )
    

    نکته فراموش نکنیم که موقع ایمپورت کردن از آکولاد استفاده کنیم.

    فهرست

  10. چرا استفاده از توابع ref callback درون خطی توصیه نمیشه؟

    اگه ref callback به عنوان یه تابع درون خطی تعریف بشه، در طول به روزرسانی دو بار فراخوانی میشه، یه بار با مقدار null و بعد دوباره با عنصر DOM. این موضوع به خاطر اینه که یه نمونه جدیدی از تابع با هر بار رندر ساخته میشه، پس ری‌اکت باید ref قبلی رو پاک کنه و یه نمونه جدید ایجاد کنه.

    class UserForm extends Component {
      handleSubmit = () => {
        console.log("Input Value is: ", this.input.value)
      }
    
    
      render () {
       return (
         <form onSubmit={this.handleSubmit}>
           <input
             type='text'
             ref={(input) => this.input = input} /> // Access DOM input in handle submit
           <button type='submit'>Submit</button>
         </form>
       )
     }
    }
    

    اما انتظار ما اینه که وقتی کامپوننت mount‌ شد، ref callback یه بار صدا زده بشه. یه راه حل سریع استفاده از class property syntax ES6 برای تعریف تابع هستش.

    class UserForm extends Component {
     handleSubmit = () => {
       console.log("Input Value is: ", this.input.value)
     }
    
     setSearchInput = (input) => {
       this.input = input
     }
    
     render () {
       return (
         <form onSubmit={this.handleSubmit}>
           <input
             type='text'
             ref={this.setSearchInput} /> // Access DOM input in handle submit
           <button type='submit'>Submit</button>
         </form>
       )
     }
    }
    

    فهرست

  11. render hijacking توی ری‌اکت چیه؟

    مفهوم render hijacking به معنی توانایی کنترل اینکه چه کامپوننتی خروجی بقیه رندر شدن یه کامپوننت دیگه باشه هست. در واقع ما می‌تونیم با قرار دادن کامپوننت خودمون توی یه کامپوننت با اولویت بالا(HOC) یه تغییراتی بهش بدیم، مثلا یه سری prop بهش اضافه کنیم یا تغییرات دیگه‌ای که باعث تغییر منطق رندر بشه. HOC در واقع hijacking رو فعال نمیکنه اما با استفاده از HOC این امکان رو فراهم می‌کنیم که کامپوننت بتونه رفتار متفاوتی رو موقع رندر داشته باشه.

    فهرست

  12. پیاده‌سازی factory یا سازنده HOC چطوریه؟

    دو روش اصلی برای اجرای HOC‌ها توی ری‌اکت وجود داره:

    1. Props Proxy (PP)

    2. Inheritance Inversion (II).

    این دو روش‌ امکان مدیریت و کنترل WrappedComponent به شکل‌های مختلف رو فراهم می کنن.

    Props Proxy

    تو این روش، متد رندر HOC یه عنصر ری‌اکت از نوع WrappedComponent رو برمی گردونه که در واقع همون کامپوننت اصلی هست که از پارامتر ورودی تابع گرفتیم. با رندر کردن اون کامپوننت توسط این تابع، propهایی که HOC دریافت میکنه رو به کامپوننت انتقال میدیم و می‌تونیم propهای دیگه‌ای هم بهش اضافه کنیم، به خاطر همین بهش Props Proxy گفته میشه.

    function ppHOC(WrappedComponent) {
     return class PP extends React.Component {
       render() {
         return <WrappedComponent {...this.props}/>
       }
     }
    }
    

    Inheritance Inversion

    توی این روش، کلاس HOC برگشت داده شده(Enhancer) از WrappedComponent دریافت شده extend میشه و به همین دلیل می‌تونیم به متدهای اون کامپوننت دسترسی داشته باشیم و با این دسترسی خیلی راحت می‌تونیم متد render رو هم فراخوانی کنیم.

    function iiHOC(WrappedComponent) {
     return class Enhancer extends WrappedComponent {
       render() {
         return super.render()
       }
     }
    }
    

    فهرست

  13. چطوری به یه کامپوننت ری‌اکت عدد پاس بدیم؟

    اعداد رو باید از طریق آکولاد همونطور که رشته رو داخل کوتیشن قرار میدیم، انتقال بدیم.

       React.render(<User age={30} department={"IT"} />, document.getElementById('container'));
    

    فهرست


  1. لازمه همه stateها رو توی ریداکس مدیریت کنیم؟ لزومی به استفاده از state داخلی داریم؟

    این به تصمیم توسعه دهنده بستگی داره ولی بهتره که از عمومی سازی داده‌های غیرضروری خودداری کنین. این وظیفه توسعه دهنده‌ست که بررسی کنه چه نوعی از state‌ها برنامه رو تشکیل بده و هر state کجا باید قرار بگیره. به شکل کلی این شرط‌ها رو قبل از انتقال state لوکال به state عمومی بررسی کنین:

    اینا قوانینی هستن که تعیین می کنن چه نوع داده ای باید توی ریداکس قرار بگیره

    1. آیا بقیه قسمتای برنامه به این داده‌ها اهمیت میدن؟

    2. آیا نیازه که بتونیم یه سری داده‌ها رو از روی این داده‌های اصلی به دست بیاریم؟

    3. آیا از این داده‌ها توی چندین کامپوننت استفاده میشه؟

    4. آیا نیازه که بتونیم یه state رو به یه بازه زمانی خاصی برگردونیم؟

    5. آیا میخوایم داده رو توی حافظه نگه داریم؟ (یعنی به جای درخواست مجدد، از اطلاعات موجود توی state استفاده کنیم)

    فهرست

  2. هدف از متد registerServiceWorker توی ری‌اکت چیه؟

    ری‌اکت به صورت پیش فرض و بدون هیچگونه پیکربندی، یه ServiceWorker برامون ایجاد میکنه. ServiceWorker یه API وب هستش که توی ذخیره کردن asset‌ها و فایل‌های دیگه بهمون کمک می‌کنه تا وقتی کاربر آفلاینه یا سرعت اینترنتش پایینه، بازم بتونه نتایج رو روی صفحه ببینه. به این ترتیب بهمون کمک میکنه تا تجربه کاربری بهتری ایجاد کنیم. با استفاده از متد registerServiceWorker که ری‌اکت فراهم می‌کنه، سرویس خودمون رو روی مرورگر کاربر نصب می‌کنیم و می‌تونیم از مزایایی که گفتیم بهره‌مند بشیم.

       import React from 'react';
       import ReactDOM from 'react-dom';
       import App from './App';
       import registerServiceWorker from './registerServiceWorker';
    
       ReactDOM.render(<App />, document.getElementById('root'));
       registerServiceWorker();
    

    فهرست


  1. چطوری با استفاده از تابع setState از رندر غیرضروری جلوگیری کنیم؟

    می‌تونیم مقدار فعلی یه state رو با مقدار موجود مقایسه کنیم و تصمیم بگیریم که state رو تغییر بدیم یا نه. میدونیم اگه یه setState غیر ضروری انجام بدیم، کامپوننت‌مون ری‌رندر میشه پس اگه مقادیر یکسان بود برای جلوگیری از رندر مجدد نباید استیت رو مجددا ست کنیم. برای مثال، اطلاعات پروفایل کاربر توی مثال زیر به صورت شرطی رندر شده:

    const getUserAddress = (user) => {
      const latestAddress = user.address;
     
      if (address !== latestAddress) {
        setAddress(address);
      }
    };
    

    فهرست

  2. توی نسخه ۱۶ ری‌اکت چطوری میشه آرایه، Strings و یا عدد رو رندر