کلاس مشاهده گر
Observer ابزاری است که به شما امکان می دهد متغیرهای استیت سراسری خود را مقداردهی کرده و آنها را از هر نقطه در برنامه خود به روز کنید.
با استفاده از Observer، علاوه بر به روز رسانی مقادیر استیت، می توانید به تغییرات مقادیر گوش دهید تا در صورت تغییر آنها از آن مطلع شوید.
به طور پیش فرض، Rosma از یک نمونه از کلاس Observer استفاده می کند. با این حال، می توانید از چندین نمونه از کلاس Observer برای مدیریت بهتر پروژه خود استفاده کنید. در بخش های بعدی این موضوع توضیح داده خواهد شد.
کلاس Observer چندین متد ارائه می دهد که در زیر لیست شده است:
observer.get
متد observer.get
برای دریافت مقادیر از استیت استفاده می شود. می توانید از این متد برای دریافت یک یا چند مقدار به طور همزمان استفاده کنید.
دریافت یک مقدار
برای دریافت فقط یک مقدار از استیت، باید کلید متغیر را به عنوان آرگومان به متد get
ارسال کنید.
برای مثال، فرض کنید مقدار foo
در استیت برابر با 'bar'
باشد. در این حالت می توانید مقدار foo
را دریافت کرده و به صورت زیر به متغیری اختصاص دهید:
import { observer } from 'rosma';
const foo = observer.get('foo');
console.log(foo); // bar
دریافت چند مقدار به صورت همزمان
اگر می خواهید بیش از یک مقدار را از استیت دریافت کنید، باید کلیدهای مورد نظر را به عنوان یک آرایه به متد get
ارسال کنید. در این حالت مقدار برگشتی از متد get
یک آبجکت
میباشد.
برای مثال، فرض کنید استیت ما حاوی مقادیر foo
برابر با 'bar'
و baz
برابر با 'qux'
باشد. برای بازیابی همزمان مقادیر foo
و baz
می توانید از کد زیر استفاده کنید:
import { observer } from 'rosma';
const values = observer.get(['foo', 'baz']);
console.log(values); // { foo: 'bar', baz: 'qux' }
همچنین در نظر داشته باشید که می توانید مانند مثال زیر مقادیر شیء برگشتی را استخراج کنید تا هر مقدار را به یک متغیر جداگانه اختصاص دهید:
import { observer } from 'rosma';
const { foo, baz } = observer.get(['foo', 'baz']);
console.log(foo, baz); // 'bar', 'qux'
observer.set
متد set
برای تغییر یا اضافه کردن یک یا چند مقدار در استیت استفاده می شود. هنگامی که یک مقدار در استیت با استفاده از متد set
تغییر میکند، همه کامپوننت هایی که از آن مقدار استفاده میکنند rerender
میشوند. با این حال، این امکان نیز وجود دارد که یک مقدار را به صورت بی صدا تغییر دهید، بدون اینکه کامپوننت هایی که از آن استفاده می کنند، rerender
شوند .
توجه داشته باشید که اگر مقداری را بهصورت بیصدا تنظیم کنید، و کامپوننتی که از آن مقدار استفاده میکند، بعداً به دلایل دیگر rerender
شود، مقدار جدید از استیت دریافت میشود.
پیش نمایش
import { observer, useObserver } from 'rosma';
export function DisplayTime() {
const { time, setTime } = useObserver('');
return (
<div>
<p>Time is: {time}</p>
<Button onClick={() => setTime(getTime())}>
Update time with setter method
</Button>
<Button onClick={() => observer.set({ time: getTime() })}>
Update time with observer.set
</Button>
<Button
onClick={() => observer.set({ time: getTime() }, { silent: true })}
>
Update time silently
</Button>
</div>
);
}
function getTime() {
return new Date().toLocaleTimeString();
}
function Button(props) {
return <button {...props} style={{ display: 'block' }} />;
}
Time is:
در این مثال، کامپوننت DisplayTime
مقدار زمان را از استیت موجود در observer
با استفاده از هوک useObserver
دریافت می کند و آن را در یک پاراگراف نمایش می دهد.
این کامپوننت همچنین شامل سه دکمه است که به کاربر امکان می دهد مقدار زمان را به روش های مختلف به روز کند. اولین دکمه متد setTime
را برای به روز رسانی مقدار با استفاده از هوک useObserver
فراخوانی می کند. دکمه دوم متد observer.set
را فراخوانی می کند تا مقدار را مستقیماً در استیت موجود در observer
به روز کند. دکمه سوم متد observer.set
را با گزینه silent
فراخوانی میکند تا مقدار را بهطور بیصدا بهروزرسانی کند، بدون اینکه هیچ کامپوننتی که از مقدار زمان استفاده میکند را rerender
کند.
یک مثال از کامپوننت مودال
این کد یک مثال ساده و کاربردی از نحوه استفاده از متد های get
و set
در observer
است. استفاده از این متد ها به کاربر این اجازه را می دهد تا کامپوننت مودال را باز و بسته کند و آنها را در در سرتاسر برنامه نمایش دهد.
app.tsx
کامپوننت App
نقطه ورود برنامه است. آن شامل دکمه ای است که باعث ایجاد شدن یک مودال جدید میشود و کامپوننت Modals
وظیفه render
کردن تمامی مودال های باز را دارد. تابع newModal
از actions.ts
ایمپورت شده تا ایجاد شدن مودال جدید را مدیریت کند.
import Modals from './modals';
import { newModal } from './actions';
export function App() {
return (
<>
<button
onClick={() => newModal({ title: 'Modal title', body: 'Modal body' })}
>
Open Modal
</button>
<Modals />
</>
);
}
modals.tsx
کامپوننت Modals
از هوک useObserver
برای دریافت آرایه modals
از استیت استفاده می کند، که داده ها را برای هر مدال باز نگه می دارد. با استفاده از تابع map
میتوان تمامی مودال های موجود را توسط کامپوننت Modal
نمایش داد . کامپوننت Modal
مسئول رندر مدال ها با title
، body
و یک دکمه close
میباشد.
import { useObserver } from 'rosma';
import { closeModal } from './actions';
export default function Modals() {
const { modals } = useObserver([]);
return modals.map((modal, index) => <Modal key={index} {...modal} />);
}
function Modal({ title, body, id }) {
return (
<div
style={{
backgroundColor: 'white',
boxShadow: '0 0 5px #ccc',
minWidth: '300px',
position: 'fixed',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)',
borderRadius: '7px',
}}
>
<div
style={{
display: 'flex',
padding: '10px',
borderBottom: '1px solid #ccc',
gap: '5px',
}}
>
<span>{title}</span>
<span>#{id}</span>
<div style={{ flex: 1 }} />
<button onClick={() => closeModal(id)}>x</button>
</div>
<div style={{ padding: '10px' }}>{body}</div>
</div>
);
}
actions.ts
فایل action
دو تابع newModal
و closeModal
را export می کند. هر دوی این توابع از نمونه observer
ارائه شده توسط کتابخانه Rosma برای بدست آوردن و تنظیم آرایه modals
در استیت سراسری استفاده می کنند. تابع newModal
یک شی مودال جدید با id
، title
و body
منحصر به فرد ایجاد می کند و آن را به آرایه modals
اضافه می کند. تابع closeModal
مودال را با شناسه داده شده از آرایه modals
فیلتر می کند.
import { observer } from 'rosma';
export function newModal({ title, body }) {
const modals = observer.get('modals') || [];
const modal = {
id: modals.length + 1,
title,
body,
};
modals.push(modal);
observer.set({ modals });
}
export function closeModal(id) {
const modals = observer.get('modals') || [];
observer.set({ modals: modals.filter((modal) => modal.id !== id) });
}
پیش نمایش
observer.state
مقدار فعلی استیت را برمیگرداند.
همانطور که قبلا ذکر شد، همه متغیرهای موجود در استیت با حروف کوچک ذخیره می شوند، در حالی که نام های بازیابی شده از مقادیر استیت به حروف بزرگ و کوچک حساس نیستند.
توجه داشته باشید که تغییر دادن استیت با استفاده از observer.state
، کامپوننت ها را ری رندر نمیکند یا listener ها را اجرا نمیکند.
import { observer } from 'rosma';
observer.set({ foo: 'bar' });
console.log(observer.state.foo); // "bar"
observer.isValid
observer.get
بررسی می کند که آیا کلید داده شده در استیت وجود دارد یا خیر. یک استرینگ به عنوان کلید دریافت می کند و تعیین می کند که آیا آن متغیر در استیت تعریف شده است یا خیر.
import { observe } from 'rosma';
observer.isValid('myVariable'); // false
observer.set({ myVariable: 'something' });
observer.isValid('myVariable'); // true
observer.subscribe
متد subscribe
برای نظارت بر تغییرات در یک یا چند متغیر در استیت استفاده می شود. این متد به دو پارامتر ورودی نیاز دارد:
-
کلید یا کلیدهای مورد نظر که می خواهید تغییراتشان را نظرات کنید.
-
یک
listener
که با تغییر کلید یا کلیدهای مورد نظر اجرا می شود.
این متد یک تابع unsubscribe
را برمیگرداند و به شما امکان میدهد که در صورت نیاز نظرات بر تغییرات متغیر ها را غیر فعال کنید. بسته به نیاز شما میتوان از این متد در داخل useEffect
یا خارج از کامپوننت React استفاده کرد. اگر نیاز به نظارت بر تغییرات چندین متغیر به طور همزمان را دارید، می توانید آنها را به عنوان یک آرایه تعریف کنید و آن را به عنوان اولین پارامتر به متد subscribe
ارسال کنید. البته توجه داشته باشید که در این حالت مقادیر مورد نظر به عنوان یک object
به تابع listener
ارسال می شود.
در بخش های بعدی بیشتر در مورد subscribe
صحبت خواهیم کرد.
پیش نمایش
import { observer, useObserver } from 'rosma';
const unsubscribe = observer.subscribe('myVar', listener);
function listener(myVar) {
alert('myVar changed! ' + myVar);
}
export function ObserverTest() {
const { setMyVar } = useObserver();
return (
<>
<button onClick={() => setMyVar(new Date())}>Click me</button>
<button onClick={unsubscribe}>Unsubscribe</button>
</>
);
}
در این مثال observer
و useObserver
را از کتابخانه rosma ایمپورت کرده. سپس با فراخوانی observer.subscribe
و ارسال نام متغیر myVar
به عنوان پارامتر اول و تابع listener به عنوان پارامتر دوم، نظرات بر تغییرات متغیر myVar
را شروع میکنیم.
کامپوننت ObserverTest
از useObserver
برای دریافت تابع setMyVar
استفاده می کند که می تواند برای به روز رسانی مقدار myVar
فراخوانی شود. آن کامپوننت دکمه ای را ارائه می کند که با کلیک کردن روی آن، setMyVar
را با یک شیء تاریخ جدید به عنوان آرگومان اجرا می کند. هنگامی که myVar
تغییر می کند، تابع listener فراخوانی می شود و یک هشدار با مقدار به روز شده myVar
نمایش داده می شود.
اگر کاربر روی دکمه لغو اشتراک کلیک کند. متد لغو اشتراک اجرا می شود و تابع listener با تغییرات myVar
دیگر فراخوانی نمی شود.
کلید واژه ها: observer, مقادیر استیت سراسری, بروزرسانی استیت, تظارت بر استیت, multiple instances, observer.get, observer.set, observer.isValid, observer.subscribe, دریافت مقادیر, گرفتن یک مقدار, گرفتن چند مقدار, تغییر یا اضافه کردن مقدار, بیصدا, پیش نمایش, کامپوننت مودال, app.tsx, modals.tsx
قبلی: هوک useObserver
بعدی: استفاده از چند مشاهده گر