از استراتژی Heist تا React State: چگونه داده ها بین مؤلفه ها جریان می یابد

زمانی که برنامه نویسی را شروع کردم، عمدتاً سعی کردم به نحوی پیش بیایم، اما وقتی پروژه هایم رشد کردند، باید به طراحی و جریان داده فکر کنم. فقط شروع به کدنویسی چیزی کنید که دیگر کار نمی کند.
برای مشخصتر کردن این مشکل، اجازه دهید در مورد اینکه چگونه کامپوننتهای React میتوانند دادهها را بین خود ارسال کنند، بحث کنیم. بیایید کمی سرگرم شویم و برنامه React خود را به عنوان گروهی از دزدان باتجربه Ocean's Eleven تصور کنیم (امیدوارم به اندازه کافی بزرگ شده باشید که این فیلم را با برد پیت جوان و جورج کلونی به خاطر بسپارید). شخصیت اصلی، دنی اوشن، دزدی که به تازگی از زندان آزاد شده است، تیمی متشکل از یازده تبهکار ماهر را گرد هم میآورد تا یک دزدی مفصل را انجام دهند. هدف آنها: سرقت همزمان سه تا از محافظتشدهترین کازینوهای لاسوگاس – Bellagio، Mirage، و MGMGrand – که همگی متعلق به تری بندیکت بیرحم هستند. این تیم با پیچ و تاب ها، تماس های نزدیک و مانورهای هوشمندانه روبرو می شود تا یکی از جسورانه ترین دزدی های تاریخ سینما را انجام دهد. بنابراین، بیایید تصور کنیم که اجزای React مجرمانی هستند که باید مخفیانه با هم ارتباط برقرار کنند.
PS: من فرصتی برای تماشای دوباره این فیلم نداشتم، بنابراین به جای تلاش برای یافتن مطابقت های دقیق در طرح، چند نمونه ساختم.
PS2: باشه. نصف فیلم رو تموم کردم چون خیلی خوبه.
بیایید شروع کنیم
1. به اشتراک گذاری داده ها با استفاده از Callbacks
در React، تماسهای برگشتی روشی متداول برای به اشتراک گذاشتن دادهها بین مؤلفهها، بهویژه از فرزند به مؤلفه والد آن است. این الگو به داده ها اجازه می دهد تا در سلسله مراتب اجزا به سمت بالا جریان پیدا کنند.
بنابراین، راستی (برد پیت) برای یافتن یک کلاهبردار بازنشسته، سائول بلوم، به مسابقه می رود و یادداشتی با دعوت نامه برای شرکت در سرقت به او می دهد. شائول پس از دریافت یک یادداشت تصمیم گرفت برود.
// Danny (Parent Component)
const SaulBloom = () => {
const [secretMessage, setSecretMessage] = useState("");
// Callback to handle the message from Rusty
const handleRustyMessage = (message) => {
setSecretMessage(message);
};
return (
);
};
// Rusty (Child Component)
const Rusty = ({ sendToDanny }) => {
const sendSignal = () => {
sendToSaul("All clear, move to the vault!"); // Sending secret signal
};
return (
Rusty: Sending Signal
);
};
2. اشتراک گذاری داده ها با استفاده از حالت
با این حال، اگر اطلاعات لازم باشد توسط همه اعضای خدمه ارائه شود، چه؟ بیایید بگوییم طرح استراتژی دزدی حالت مشترک است. مؤلفه والد (مانند دنی اوشن) برنامه را مدیریت می کند. همه اعضای خدمه نیاز به دسترسی به این اطلاعات دارند. شاید آنها از برخی از اسناد Google مشروط استفاده می کنند که دنی این طرح را پست کرده است و اعضا آن را خوانده یا به روز کرده اند.
در React، از حالت برای به اشتراک گذاری و مدیریت داده ها در داخل و بین اجزا استفاده می شود. هنگامی که حالت به یک مؤلفه والد مشترک ارتقا می یابد، می تواند به عنوان یک منبع واحد از حقیقت برای مؤلفه های فرزند خود عمل کند و به اشتراک گذاری داده ها را آسان کند.
function CrewMeeting() {
const [plan, setPlan] = useState('Rob Bellagio at 11 PM');
const updatePlan = () => {
setPlan('Rob Bellagio and MGM Grand at 10 PM');
};
return (
Current Plan: {plan}
);
}
function CrewMember({ name, plan }) {
return (
👤 {name}
📝 Plan: {plan}
);
}
3. به اشتراک گذاری داده ها با استفاده از رویدادهای سفارشی
طرح آماده است و Ocean's Eleven باید کازینو را بررسی کند. با این حال، ارسال یادداشت های کاغذی در داخل ساختمان بسیار کند است و استفاده از لپ تاپ ناخوشایند است. بنابراین آنها باید از قبل در مورد علائم مطمئن تصمیم بگیرند. به عنوان مثال، فرانک کاتو، که نقش یک کروپیر بی اعتبار را در نقشه بازی خواهد کرد، می بیند که چگونه سائول وارد می شود و می داند که سرقت شروع می شود.
این مثال رویدادهای سفارشی در React را نشان می دهد. در اینجا، آنها مانند جاوا اسکریپت وانیلی داخلی نیستند. با این حال، هنوز هم میتوانید با استفاده از ابزارهایی مانند کلاس EventEmitter یا کتابخانههای شخص ثالث مانند PubSub یا EventTarget به یک معماری رویداد محور سفارشی دست پیدا کنید. در زندگی واقعی، ما از این الگو استفاده میکنیم و اجزایی که باید به هم متصل شوند به هم نزدیک نیستند، بنابراین حفاری پایهها منطقی نیست. برای مثال، اگر بعد از بسته شدن ماژول نیاز به نمایش بنر فروش داشته باشیم.
در اینجا کد استعاره اقیانوس است.
// create eventBus.js
const eventBus = new EventTarget();
//event emitter component
function SaulBloom() {
const sendArrivalSignal = () => {
console.log('🕴️ Saul Bloom: Enters the casino as the wealthy foreigner.');
// Emit the custom event 'heistStart'
eventBus.dispatchEvent(new CustomEvent('heistStart', { detail: 'Saul has arrived' }));
};
return (
🕴️ Saul Bloom
);
}
//event listener component
function FrankCatton() {
const [status, setStatus] = useState('Waiting for the signal...');
useEffect(() => {
// Listen for the 'heistStart' event
const handleHeistStart = (event) => {
console.log('🎲 Frank Catton: Received the signal! The heist begins.');
setStatus(`Signal received: ${event.detail}`);
};
eventBus.addEventListener('heistStart', handleHeistStart);
// Cleanup listener on component unmount
return () => {
eventBus.removeEventListener('heistStart', handleHeistStart);
};
}, []);
return (
🎲 Frank Catton
{status}
);
}
4. به اشتراک گذاری داده ها با استفاده از Broadcast Channel API
در تنظیمات قبلی، اعضای تیم حداقل میتوانستند یکدیگر را ببینند، اما اگر در مکانهای مختلف قرار داشتند و نمیتوانستند مستقیماً ارتباط برقرار کنند، چه؟ تنها ذخیرهکننده Broadcast Channel API است.
Broadcast Channel API یک راه حل بومی مرورگر برای به اشتراک گذاری داده ها بین برگه های مرورگر، پنجره ها یا iframe ها از مبدأ دقیق است. این به عنوان یک کانال ارتباطی برای پخش پیام ها به تمام زمینه های مرتبط عمل می کند.
بشیر تار، کارشناس تخریب خدمه و هکر در حساس ترین نقطه فیلم، برق کازینو را با استفاده از دستگاه EMP (پالس الکترومغناطیسی) قطع می کند. سپس همه می دانند که زمان آن فرا رسیده است که به خزانه نفوذ کنند.
//set up a channel to broadcast the EMP signal
const heistChannel = new BroadcastChannel("heistChannel");
// BasherTarr component and event emitter
function BasherTarr() {
const triggerEMP = () => {
const message = "EMP Triggered: Lights Out!";
heistChannel.postMessage(message); // Broadcast message to all tabs
console.log("💥 EMP Triggered - Message Sent");
};
return (
🛠️ Basher Tarr (EMP Specialist)
);
}
//event receiver component
function CrewMember({ name }) {
const [status, setStatus] = useState("Waiting for signal...");
useEffect(() => {
// Listen for messages from the heist channel
const handleEMP = (event) => {
setStatus("Going into the vault");
};
heistChannel.addEventListener("message", handleEMP);
// Cleanup listener when component unmounts
return () => {
heistChannel.removeEventListener("message", handleEMP);
};
}, [name]);
return (
👤 {name}
🔌 Status: {status}
);
}
5. به اشتراک گذاری داده ها با استفاده از EventBus
دو تکنیک قبلی فوقالعاده کار میکنند، اما اگر تعداد زیادی فرستنده، گیرنده و رویداد داشته باشیم، میتوانند کثیف شوند. در طول سرقت، لیوینگستون دل، یک کارشناس نظارت، با تمام اعضای خدمه ارتباط برقرار می کند و به آنها می گوید که چه زمانی زمان اقدام فرا رسیده است.
EventBus یک سیستم انتشار/اشتراک (pub/sub) ساده است که در آن اجزا می توانند رویدادها را منتشر کنند و دیگران می توانند گوش دهند. این کار از ارتباط مستقیم یا حفاری پایه جلوگیری می کند و در عین حال سیستم را تمیز و منظم نگه می دارد.
// TypedEventBus.js
class TypedEventBus {
constructor() {
this.eventBus = new EventBus();
}
/**
* Subscribes to a specific topic.
* @param {string} topic - Event name.
* @param {(payload: any) => void} listener - Listener function.
*/
subscribe(topic, listener) {
this.eventBus.subscribe(topic, listener);
}
/**
* Unsubscribes from a specific topic.
* @param {string} topic - Event name.
* @param {(payload: any) => void} listener - Listener function.
*/
unsubscribe(topic, listener) {
this.eventBus.unsubscribe(topic, listener);
}
/**
* Publishes an event with a typed payload.
* @param {string} topic - Event name.
* @param {any} payload - Event payload.
*/
publish(topic, payload) {
this.eventBus.publish(topic, payload);
}
}
// Create a singleton EventBus instance
const eventBus = new TypedEventBus();
export default eventBus;
// LivingstonDell.js
function LivingstonDell() {
const sendSignal = (topic, message) => {
eventBus.publish(topic, message);
};
return (
📡 Livingston Dell (Surveillance Expert)
);
}
من از هرگونه پیشنهاد و اصلاحی از سوی کالج ها خوشحال خواهم شد زیرا مطمئن هستم که راه های زیادی برای اصلاح این مقاله وجود دارد.
همچنین میخواهم قسمت دوم این مقاله را ایجاد کنم که در آن اتصالات با استفاده از iframes، integration-through-back-end-websocket، integration-through-back-end-long-polling، integration-through-stories (مثلاً db index )، ادغام-از طریق-URL، ادغام-ازطریق-عنصر سومین دامنه. اما خواهد بود.
ممنون که خواندید