مرور سریع فرانتاند (React، TypeScript و ابزارها)
جمعبندی نکات کلیدی React، ES6، TypeScript، Redux و ابزارهای سمت کلاینت برای مرور شب قبل مصاحبه.
این جزوه مهمترین نکات React و اکوسیستم فرانتاند مدرن را که در مصاحبههای برنامهنویسی پرتکرارند، در یک صفحه جمع کرده تا در کمترین زمان مرور کنید. نکات ⭐ (طلایی) پرتکرارترین سؤالات مصاحبه هستند — اگر وقت کم دارید، فقط همانها را بخوانید.
فهرست بخشها
- React.js — مبانی و Hookهای پرکاربرد0/8
- ES6 (ECMAScript 2015) — ویژگیهای کلیدی جاوااسکریپت مدرن0/5
- PWA (Progressive Web App)0/5
- Tailwind CSS — فریمورک Utility-First0/5
- TypeScript = JavaScript + Type System0/5
- AJAX — ارسال درخواست بدون رفرش صفحه0/5
- Redux — مدیریت State متمرکز0/5
- Worker Service (Background Service) در ASP.NET Core0/4
- Webpack — Module Bundler0/5
React.js — مبانی و Hookهای پرکاربرد0/8
React یک کتابخانهٔ جاوااسکریپت برای ساخت رابط کاربری است که Meta آن را توسعه داده؛ مبتنی بر Component، Virtual DOM و State.
function Welcome() {
return <h1>سلام</h1>;
}
function App() {
return <h1>React Learning</h1>;
}
function User(props) {
return <h2>{props.name}</h2>;
}
<User name="Ali" />
const [count, setCount] = useState(0);
setCount(count + 1);
پاسخ سریع برای «فرق Props و State چیست؟»: Props از بیرون کامپوننت میآید و immutable است؛ State داخل خود کامپوننت مدیریت میشود و mutable است.
const [name, setName] = useState("");
useEffect(() => {
console.log("Loaded");
}, []);
Hookها یکی از پرتکرارترین سوالات مصاحبهٔ React هستند؛ حتماً تفاوت آرایهٔ وابستگی خالی [] (فقط یکبار) و بدون آرایه (هر رندر) را در useEffect توضیح بده.
useEffect(() => {
console.log("Mounted");
return () => {
console.log("Unmounted");
};
}, []);
{isLogin ? <Dashboard /> : <Login />}
users.map(user =>
<li key={user.id}>{user.name}</li>
)
استفاده از index آرایه بهعنوان key در لیستهای قابل تغییر (افزودن/حذف/جابهجایی) که میتواند باعث رندر اشتباه و باگهای ظریف UI شود.
function useCounter() {
const [count, setCount] = useState(0);
return { count, setCount };
}
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
ES6 (ECMAScript 2015) — ویژگیهای کلیدی جاوااسکریپت مدرن0/5
نسخهای از جاوااسکریپت که syntax مدرن (let/const، Arrow Function، Class، Destructuring، Promise و Module) را وارد زبان کرد و پایهٔ جاوااسکریپت امروزی است.
// قبل از ES6
var name = "Ali";
// در ES6
let age = 25; // قابل تغییر - block scope
const pi = 3.14; // ثابت - غیرقابل تغییر
// مثال خطا
let score = 10;
score = 20; // درست
const country = "Iran";
country = "USA"; // خطا!
تفاوت var/let/const از پرتکرارترین سوالات مصاحبهٔ جاوااسکریپت است؛ روی block scope و temporal dead zone تاکید کن.
تصور اینکه const یعنی object کاملاً immutable است؛ در واقع فقط reference قابل تغییر نیست، propertyهای داخل object قابل تغییرند.
// Template Literal
let name = "Ali";
console.log(`Hello ${name}`);
// Arrow Function
const sum = (a, b) => a + b;
// آرایه
const numbers = [10, 20, 30];
const [a, b] = numbers;
console.log(a); // 10
console.log(b); // 20
// آبجکت
const user = { name: "Ali", age: 20 };
const { name, age } = user;
// ترکیب آرایهها
const arr1 = [1, 2];
const arr2 = [3, 4];
const result = [...arr1, ...arr2];
console.log(result); // [1,2,3,4]
// ترکیب آبجکت
const user = { name: "Ali" };
const newUser = { ...user, age: 25 };
// Class
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello ${this.name}`);
}
}
const p = new Person("Ali");
p.sayHello();
// Promise
const promise = new Promise((resolve, reject) => {
resolve("Success");
});
promise.then(result => console.log(result));
// Module
export const name = "Ali";
import { name } from "./user.js";
PWA (Progressive Web App)0/5
PWA یعنی یک وبسایت که مثل اپلیکیشن موبایل رفتار میکند: قابل نصب، قابل استفاده آفلاین و سریع.
{
"name": "My App",
"short_name": "App",
"start_url": "/",
"display": "standalone",
"icons": []
}
اشتباه رایج این است که Service Worker مرورگر (برای PWA) با Worker Service سمت سرور در داتنت اشتباه گرفته شود؛ این دو مفهوم کاملاً متفاوتاند.
Tailwind CSS — فریمورک Utility-First0/5
بهجای نوشتن CSS دستی، از کلاسهای آماده (utility class) مستقیم داخل HTML برای استایلدهی سریع استفاده میشود.
<button class="bg-blue-500 text-white p-4 rounded-md">
کلیک کن
</button>
<h1 class="text-3xl font-bold text-blue-600">سلام</h1>
<div class="bg-green-500"></div>
<div class="p-4 py-2"></div>
<div class="mx-auto"></div>
<div class="flex justify-center items-center">...</div>
<div class="grid grid-cols-3 gap-4">...</div>
<div class="w-full md:w-1/2"></div>
<button class="bg-blue-500 hover:bg-blue-700">دکمه</button>
TypeScript = JavaScript + Type System0/5
TypeScript روی جاوااسکریپت یک لایهٔ Type اضافه میکند که خطاها را در زمان کامپایل (نه در Runtime) پیدا میکند.
// JavaScript
let age = 25;
// TypeScript
let age: number = 25;
let name: string = "Ali";
let isAdmin: boolean = true;
type User = {
name: string;
age: number;
};
interface User2 {
name: string;
age: number;
}
const user1: User = { name: "Ali", age: 30 };
let id: string | number;
id = 1;
id = "abc";
enum Role {
Admin,
User,
Guest
}
let role: Role = Role.Admin;
function getData<T>(value: T): T {
return value;
}
getData<string>("Hello");
getData<number>(100);
Generics از سوالات کلاسیک مصاحبهٔ TypeScript پیشرفته است؛ بلد باش توضیح بدهی چرا any جایگزین خوبی برای آن نیست.
class User {
public name: string;
private password: string;
constructor(name: string, password: string) {
this.name = name;
this.password = password;
}
}
async function getUsers(): Promise<string[]> {
return ["Ali", "Sara"];
}
AJAX — ارسال درخواست بدون رفرش صفحه0/5
AJAX یعنی ارسال درخواست به سرور و آپدیت بخشی از صفحه بدون Reload کامل.
fetch('/api/product')
.then(res => res.json())
.then(data => {
document.getElementById("result").innerText = data.name;
});
[HttpGet("api/product")]
public IActionResult GetProduct()
{
return Ok(new { name = "Laptop" });
}
$.ajax({
url: '/api/product',
type: 'GET',
success: function(data) {
$("#result").text(data.name);
}
});
اگر در مصاحبه دربارهٔ تفاوت روش قدیمی و جدید AJAX در داتنت پرسیدند، روی 'Web API بهجای PostBack/ViewState' تاکید کن.
Redux — مدیریت State متمرکز0/5
Redux یک کتابخانهٔ مدیریت State متمرکز است که دادهٔ برنامه را در یک Store واحد نگه میدارد و مشکل Prop Drilling را حل میکند.
// App -> Header -> Profile
<App user={user}>
<Header user={user}>
<Profile user={user}>
// Store
{ user: { name: "Ali" } }
// Action
{ type: "SET_USER" }
{ type: "ADD_TO_CART", payload: product }
// Reducer
function userReducer(state, action) {
switch (action.type) {
case "SET_USER":
return { ...state, name: action.payload };
default:
return state;
}
}
این سه مفهوم پرتکرارترین سوال مصاحبهٔ Redux است؛ حتماً جریان یکطرفهٔ داده (unidirectional data flow) را هم توضیح بده.
فراموشکردن اینکه Reducer باید Pure باشد (بدون side effect و بدون تغییر مستقیم state) و همیشه باید یک state جدید برگرداند نه mutate کردن state قبلی.
// npm install @reduxjs/toolkit react-redux
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { value: 0 },
reducers: {
increment: (state) => { state.value += 1; },
decrement: (state) => { state.value -= 1; }
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
// Store
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";
export const store = configureStore({
reducer: { counter: counterReducer }
});
import { Provider } from "react-redux";
<Provider store={store}>
<App />
</Provider>
// خواندن state
import { useSelector } from "react-redux";
const count = useSelector(state => state.counter.value);
// تغییر state
import { useDispatch } from "react-redux";
import { increment } from "./counterSlice";
const dispatch = useDispatch();
dispatch(increment());
Worker Service (Background Service) در ASP.NET Core0/4
این بخش دربارهٔ Worker Service سمت سرور در داتنت (پردازش پسزمینه بدون UI) است، نه Service Worker مرورگر که برای کش و آفلاینکردن در PWA استفاده میشود.
اشتباه رایج، یکیگرفتن این مفهوم با Service Worker مرورگر (برای PWA/آفلاین) است؛ این دو کاملاً متفاوتاند: یکی سمت سرور و یکی سمت مرورگر.
public class MyWorker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Console.WriteLine("Running background task...");
await Task.Delay(5000, stoppingToken);
}
}
}
// ثبت در Program.cs
builder.Services.AddHostedService<MyWorker>();
Webpack — Module Bundler0/5
Webpack ابزاری است که فایلهای JS، CSS، تصاویر و فونتهای پروژه را بررسی و در نهایت در یک یا چند فایل خروجی بهینه بستهبندی (bundle) میکند.
import { sum } from "./math.js";
import "./style.css";
// webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
}
};
// npm install css-loader style-loader --save-dev
module: {
rules: [
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
]
}
// npm install html-webpack-plugin --save-dev
plugins: [
new HtmlWebpackPlugin()
]
تفاوت Loader و Plugin سوال کلاسیک مصاحبهٔ Webpack است: Loader روی تکتک فایلها قبل از بستن (bundle) عمل میکند، Plugin روی کل فرآیند build.
// webpack.config.js
mode: "development" // یا "production"
devServer: {
port: 3000
}
// npm install webpack-dev-server --save-dev
// npx webpack serve
