মধ্যে পড়ে না একটি লাইব্রেরি চিন্তা সবকিছু কেমন করতে বিহিত করা উচিত ফাঁদ । আপনি যদি জাভাস্ক্রিপ্টের সময়সীমা নিয়ে কিছু করতে চান তবে আপনার ব্যবহার করা দরকার setTimeout
। রেডাক্স ক্রিয়াগুলি আলাদা হওয়া উচিত বলে কোনও কারণ নেই।
রেডাক্স করে অ্যাসিঙ্ক্রোনাস কাপড় সাথে ডিল করার কিছু বিকল্প উপায় প্রস্তাব, কিন্তু যখন আপনি বোঝেন যে আপনি অত্যধিক কোড পুনরায় আছেন কেবলমাত্র সেই ব্যবহার করা উচিত। আপনার যদি এই সমস্যা না হয় তবে ভাষাটি যা দেয় তা ব্যবহার করুন এবং সহজ সমাধানের জন্য যান।
অ্যাসিঙ্ক কোড ইনলাইন লেখা
এটি এখন পর্যন্ত সবচেয়ে সহজ উপায়। এবং এখানে রেডাক্সের সাথে নির্দিষ্ট কিছু নেই।
store.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
store.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)
একইভাবে, একটি সংযুক্ত উপাদানটির ভিতরে থেকে:
this.props.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
this.props.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)
পার্থক্যটি হ'ল কোনও সংযুক্ত উপাদানটিতে সাধারণত আপনি নিজেই স্টোরটি অ্যাক্সেস করতে পারেন না, তবে হয় dispatch()
বা নির্দিষ্ট ক্রিয়াকর্মীদের প্রপস হিসাবে ইনজেকশন পান। তবে এটি আমাদের জন্য কোনও পার্থক্য করে না।
আপনি যদি বিভিন্ন উপাদান থেকে একই ক্রিয়াকলাপটি প্রেরণ করার সময় টাইপগুলি তৈরি করতে পছন্দ না করেন তবে অ্যাকশন অবজেক্টগুলিকে ইনলাইন প্রেরণের পরিবর্তে আপনি অ্যাকশন স্রষ্টাকে আহরণ করতে চাইতে পারেন:
// actions.js
export function showNotification(text) {
return { type: 'SHOW_NOTIFICATION', text }
}
export function hideNotification() {
return { type: 'HIDE_NOTIFICATION' }
}
// component.js
import { showNotification, hideNotification } from '../actions'
this.props.dispatch(showNotification('You just logged in.'))
setTimeout(() => {
this.props.dispatch(hideNotification())
}, 5000)
বা, আপনি যদি আগে তাদের সাথে আবদ্ধ হন connect()
:
this.props.showNotification('You just logged in.')
setTimeout(() => {
this.props.hideNotification()
}, 5000)
এখন পর্যন্ত আমরা কোনও মিডলওয়্যার বা অন্যান্য উন্নত ধারণা ব্যবহার করি নি।
অ্যাসিঙ্ক অ্যাকশন স্রষ্টা সরিয়ে নেওয়া হচ্ছে
উপরের পদ্ধতিটি সাধারণ ক্ষেত্রে ঠিকঠাক কাজ করে তবে আপনি দেখতে পাবেন যে এতে কয়েকটি সমস্যা রয়েছে:
- এটি আপনাকে কোনও নোটিফিকেশন দেখাতে চাইলে এই যুক্তিকে সদৃশ করতে বাধ্য করে forces
- বিজ্ঞপ্তিগুলির কোনও আইডি নেই তাই যদি আপনি দুটি বিজ্ঞপ্তি দ্রুত পর্যায়ে দেখান তবে আপনার কাছে একটি জাতি শর্ত থাকবে। প্রথম টাইমআউট শেষ হয়ে গেলে, এটি প্রেরণ করবে
HIDE_NOTIFICATION
, ভুলক্রমে দ্বিতীয় বিজ্ঞপ্তিটি সময়সীমার পরে খুব শীঘ্রই লুকিয়ে রাখবে।
এই সমস্যাগুলি সমাধান করার জন্য, আপনাকে একটি ফাংশন নিষ্কাশন করতে হবে যা সময়সীমা যুক্তিকে কেন্দ্রীভূত করে এবং এই দুটি ক্রিয়া প্রেরণ করে। এটি দেখতে এটির মতো দেখাবে:
// actions.js
function showNotification(id, text) {
return { type: 'SHOW_NOTIFICATION', id, text }
}
function hideNotification(id) {
return { type: 'HIDE_NOTIFICATION', id }
}
let nextNotificationId = 0
export function showNotificationWithTimeout(dispatch, text) {
// Assigning IDs to notifications lets reducer ignore HIDE_NOTIFICATION
// for the notification that is not currently visible.
// Alternatively, we could store the timeout ID and call
// clearTimeout(), but we’d still want to do it in a single place.
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
}, 5000)
}
এখন উপাদানগুলি showNotificationWithTimeout
এই যুক্তিকে অনুলিপি করা বা বিভিন্ন বিজ্ঞপ্তি সহ জাতিদের শর্ত না করে ব্যবহার করতে পারে :
// component.js
showNotificationWithTimeout(this.props.dispatch, 'You just logged in.')
// otherComponent.js
showNotificationWithTimeout(this.props.dispatch, 'You just logged out.')
কেন প্রথম যুক্তি হিসাবে showNotificationWithTimeout()
গ্রহণ dispatch
? কারণ এটি ক্রিয়াকলাপ দোকানে প্রেরণ করা প্রয়োজন। সাধারণত কোনও উপাদানটির অ্যাক্সেস থাকে dispatch
তবে আমরা যেহেতু বাহ্যিক ফাংশন প্রেরণের উপর নিয়ন্ত্রণ নিতে চাই তাই আমাদের এটি প্রেরণের উপর নিয়ন্ত্রণ দেওয়া দরকার।
যদি আপনি কোনও মডিউল থেকে একটি সিঙ্গলটন স্টোর রফতানি করে থাকেন তবে আপনি কেবল এটির এবং dispatch
সরাসরি তার পরিবর্তে আমদানি করতে পারেন :
// store.js
export default createStore(reducer)
// actions.js
import store from './store'
// ...
let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
const id = nextNotificationId++
store.dispatch(showNotification(id, text))
setTimeout(() => {
store.dispatch(hideNotification(id))
}, 5000)
}
// component.js
showNotificationWithTimeout('You just logged in.')
// otherComponent.js
showNotificationWithTimeout('You just logged out.')
এটি সহজ দেখাচ্ছে তবে আমরা এই পদ্ধতির প্রস্তাব দিই না । আমরা এটিকে অপছন্দ করার মূল কারণ হ'ল এটি স্টোরকে একটি সিঙ্গলটন হতে বাধ্য করে । এটি সার্ভার রেন্ডারিং বাস্তবায়ন করা খুব শক্ত করে তোলে । সার্ভারে, আপনি প্রতিটি অনুরোধটির নিজস্ব স্টোর রাখতে চাইবেন, যাতে বিভিন্ন ব্যবহারকারী বিভিন্ন প্রিলোডড ডেটা পান।
একটি সিঙ্গলটন স্টোরও পরীক্ষা আরও শক্ত করে তোলে। অ্যাকশন স্রষ্টাদের পরীক্ষা করার সময় আপনি আর কোনও স্টোরকে উপহাস করতে পারবেন না কারণ তারা নির্দিষ্ট মডিউল থেকে রফতানি করা একটি নির্দিষ্ট রিয়েল স্টোরের উল্লেখ করে। আপনি এর রাজ্যটি বাইরে থেকে পুনরায় সেট করতে পারবেন না।
সুতরাং আপনি যখন প্রযুক্তিগতভাবে কোনও মডিউল থেকে একটি সিঙ্গলটন স্টোর রফতানি করতে পারেন, আমরা এটি নিরুৎসাহিত করি। আপনার অ্যাপটি কখনই সার্ভার রেন্ডারিং যুক্ত করবে না এমনটি নিশ্চিত না হলে এটি করবেন না।
পূর্ববর্তী সংস্করণে ফিরে আসা:
// actions.js
// ...
let nextNotificationId = 0
export function showNotificationWithTimeout(dispatch, text) {
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
}, 5000)
}
// component.js
showNotificationWithTimeout(this.props.dispatch, 'You just logged in.')
// otherComponent.js
showNotificationWithTimeout(this.props.dispatch, 'You just logged out.')
এটি যুক্তির অনুলিপিকরণ সহ সমস্যাগুলি সমাধান করে এবং বর্ণের পরিস্থিতি থেকে আমাদের বাঁচায়।
থংক মিডলওয়্যার
সহজ অ্যাপ্লিকেশনগুলির জন্য, পদ্ধতির যথেষ্ট হওয়া উচিত। আপনি যদি এতে সন্তুষ্ট হন তবে মিডলওয়্যার সম্পর্কে চিন্তা করবেন না।
বৃহত্তর অ্যাপ্লিকেশনগুলিতে, তবে আপনার আশেপাশে কিছু অসুবিধা খুঁজে পেতে পারে।
উদাহরণস্বরূপ, এটি দুর্ভাগ্যজনক বলে মনে হচ্ছে যে আমাদের dispatch
চারপাশে যেতে হবে। এটি কনটেইনার এবং উপস্থাপক উপাদানগুলি পৃথক করা শক্ত করে তোলে কারণ যে কোনও উপাদান যা উপরের পদ্ধতিতে সংযোজিতভাবে Redux ক্রিয়া প্রেরণ করে সেটিকে dispatch
প্রপ হিসাবে গ্রহণ করতে হবে যাতে এটি আরও পাস করতে পারে। আপনি কেবল অ্যাকশন নির্মাতাদের সাথে connect()
আর আবদ্ধ করতে পারবেন না কারণ showNotificationWithTimeout()
সত্যই কোনও অ্যাকশন স্রষ্টা নয়। এটি কোনও রেডাক্স ক্রিয়া ফিরিয়ে দেয় না।
তদ্ব্যতীত, কোন ফাংশনগুলি সিঙ্ক্রোনাস অ্যাকশন নির্মাতাদের মতো showNotification()
এবং কোনটি অ্যাসিনক্রোনাস সহায়ক পছন্দ করে তা মনে রাখা অবাস্তব হতে পারে showNotificationWithTimeout()
। আপনাকে এগুলি আলাদাভাবে ব্যবহার করতে হবে এবং একে অপরের সাথে ভুল না করার বিষয়ে সতর্ক থাকতে হবে।
সহায়তাকারী ফাংশন সরবরাহ dispatch
করার এই প্যাটার্নটিকে "বৈধতা দেওয়ার" উপায় খুঁজে বের করার প্রেরণা ছিল এবং রেডাক্স যেমন অ্যাসিনক্রোনাস অ্যাকশন নির্মাতাদের সম্পূর্ণ ভিন্ন ফাংশন না করে সাধারণ ক্রিয়া নির্মাতাদের একটি বিশেষ ক্ষেত্রে হিসাবে "দেখতে" সহায়তা করে।
আপনি যদি এখনও আমাদের সাথে থাকেন এবং আপনি যদি আপনার অ্যাপ্লিকেশনটিতে একটি সমস্যা হিসাবে স্বীকৃতি পান তবে আপনাকে রেডাক্স থাঙ্ক মিডলওয়্যারটি ব্যবহার করতে স্বাগত জানানো হবে ।
সংক্ষেপে, রেডাক্স থাঙ্ক রেডাক্সকে বিশেষ ধরণের ক্রিয়াকলাপগুলি সনাক্ত করতে শেখায় যা সত্যিকারের কার্যাদি:
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
const store = createStore(
reducer,
applyMiddleware(thunk)
)
// It still recognizes plain object actions
store.dispatch({ type: 'INCREMENT' })
// But with thunk middleware, it also recognizes functions
store.dispatch(function (dispatch) {
// ... which themselves may dispatch many times
dispatch({ type: 'INCREMENT' })
dispatch({ type: 'INCREMENT' })
dispatch({ type: 'INCREMENT' })
setTimeout(() => {
// ... even asynchronously!
dispatch({ type: 'DECREMENT' })
}, 1000)
})
এই মিডওয়্যারটি সক্ষম থাকলে, আপনি যদি কোনও ফাংশন প্রেরণ করেন তবে রেডাক্স থাঙ্ক মিডলওয়্যার এটি dispatch
আর্গুমেন্ট হিসাবে দেবে । এটি এই জাতীয় ক্রিয়াকলাপগুলিকে "গিলতেও" দেবে তাই আপনার হ্রাসকারীদের উদ্ভট ফাংশন যুক্তি পাওয়ার বিষয়ে চিন্তা করবেন না। আপনার হ্রাসকারীরা কেবল প্লেইন অবজেক্ট ক্রিয়াগুলি গ্রহণ করবে - হয় প্রত্যক্ষভাবে নির্গত হয়, বা আমরা সুনির্দিষ্টভাবে বর্ণনা হিসাবে ফাংশনগুলি দ্বারা নির্গত হয়।
এটি খুব দরকারী বলে মনে হচ্ছে না, তাই না? এই বিশেষ পরিস্থিতিতে নয়। তবে এটি আমাদের showNotificationWithTimeout()
নিয়মিত রেডাক্স অ্যাকশন নির্মাতা হিসাবে ঘোষণা করতে দেয় :
// actions.js
function showNotification(id, text) {
return { type: 'SHOW_NOTIFICATION', id, text }
}
function hideNotification(id) {
return { type: 'HIDE_NOTIFICATION', id }
}
let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
return function (dispatch) {
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
}, 5000)
}
}
পূর্ববর্তী বিভাগে আমরা যেভাবে লিখেছি তার সাথে ফাংশনটি প্রায় একই রকম দেখুন। তবে এটি dispatch
প্রথম যুক্তি হিসাবে গ্রহণ করে না । এর পরিবর্তে এটি ফেরৎ একটি ফাংশন যে গ্রহণ করে dispatch
প্রথম আর্গুমেন্ট হিসাবে।
কীভাবে আমরা আমাদের উপাদানগুলিতে এটি ব্যবহার করব? অবশ্যই, আমরা এটি লিখতে পারে:
// component.js
showNotificationWithTimeout('You just logged in.')(this.props.dispatch)
কেবলমাত্র চায় এমন অভ্যন্তরীণ ফাংশনটি পেতে আমরা অ্যাসিঙ্ক অ্যাকশন স্রষ্টাকে কল করছি dispatch
এবং তারপরে আমরা পাস করি dispatch
।
তবে এটি মূল সংস্করণের চেয়ে আরও বিশ্রী! কেন আমরা এমনকি সে পথে গেলাম?
আমি আপনাকে আগে যা বলেছিলাম তার কারণেই। যদি রেডাক্স থাঙ্ক মিডলওয়্যার সক্ষম থাকে, আপনি যে কোনও সময় অ্যাকশন অবজেক্টের পরিবর্তে কোনও ফাংশন প্রেরণের চেষ্টা করবেন, মিডলওয়্যার সেই ফাংশনটিকে dispatch
নিজেই প্রথম আর্গুমেন্ট হিসাবে কল করবে ।
সুতরাং আমরা পরিবর্তে এটি করতে পারেন:
// component.js
this.props.dispatch(showNotificationWithTimeout('You just logged in.'))
অবশেষে, একটি অ্যাসিনক্রোনাস অ্যাকশন প্রেরণ করা (সত্যিকার অর্থে, ক্রিয়াগুলির একটি সিরিজ) উপাদানটিতে সিঙ্ক্রোনালি কোনও একক ক্রিয়া প্রেরণ করার চেয়ে আলাদা নয় looks কোনটি ভাল কারণ উপাদানগুলি সিঙ্ক্রোনালি বা অ্যাসিক্রোনোরিয়ালি কিছু ঘটে কিনা তা বিবেচনা করা উচিত নয়। আমরা কেবল এটি দূরে বিমূর্ত।
লক্ষ্য করুন যেহেতু আমরা রেডাক্সকে এই জাতীয় "বিশেষ" অ্যাকশন নির্মাতাদের চিনতে "শিখিয়েছি" (আমরা তাদেরকে থাঙ্ক অ্যাকশন স্রষ্টা বলি ), এখন আমরা এগুলিকে যে কোনও জায়গায় নিয়মিত কর্ম নির্মাতাদের ব্যবহার করতে পারি। উদাহরণস্বরূপ, আমরা এগুলি এগুলি ব্যবহার করতে পারি connect()
:
// actions.js
function showNotification(id, text) {
return { type: 'SHOW_NOTIFICATION', id, text }
}
function hideNotification(id) {
return { type: 'HIDE_NOTIFICATION', id }
}
let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
return function (dispatch) {
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
}, 5000)
}
}
// component.js
import { connect } from 'react-redux'
// ...
this.props.showNotificationWithTimeout('You just logged in.')
// ...
export default connect(
mapStateToProps,
{ showNotificationWithTimeout }
)(MyComponent)
থিংস স্টেট রিডিং
সাধারণত আপনার হ্রাসকারীদের পরবর্তী অবস্থা নির্ধারণের জন্য ব্যবসায় যুক্তিযুক্ত থাকে। তবে, ক্রিয়াগুলি প্রেরণের পরে হ্রাসকারীরা কেবল লাথি মারবে। আপনার যদি কোনও থঙ্ক অ্যাকশন নির্মাতার কোনও পার্শ্ব প্রতিক্রিয়া (যেমন কোনও এপিআই কল করা) হয় এবং আপনি কোনও শর্তে এটি আটকাতে চান তবে কী হবে?
থাঙ্ক মিডলওয়্যারটি ব্যবহার না করে আপনি কেবল উপাদানটির ভিতরে এই চেকটি করতে চাইবেন:
// component.js
if (this.props.areNotificationsEnabled) {
showNotificationWithTimeout(this.props.dispatch, 'You just logged in.')
}
তবে, অ্যাকশন স্রষ্টাকে বের করার বিষয়টি হ'ল বহু উপাদানগুলিতে এই পুনরাবৃত্তি যুক্তিটিকে কেন্দ্রিক করে তোলা। ভাগ্যক্রমে, রেডাক্স থাঙ্ক আপনাকে রেডাক্স স্টোরের বর্তমান অবস্থা পড়ার জন্য একটি উপায় সরবরাহ করে। ছাড়াও dispatch
, এটি পাস getState
ফাংশন আপনি আপনার thunk কর্ম স্রষ্টা থেকে ফিরে দ্বিতীয় আর্গুমেন্ট হিসাবে। এটি থঙ্ককে স্টোরের বর্তমান অবস্থা পড়তে দেয়।
let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
return function (dispatch, getState) {
// Unlike in a regular action creator, we can exit early in a thunk
// Redux doesn’t care about its return value (or lack of it)
if (!getState().areNotificationsEnabled) {
return
}
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
}, 5000)
}
}
এই প্যাটার্নটি অপব্যবহার করবেন না। ক্যাশেড ডেটা উপলভ্য হলে এপিআই কলগুলি জামিন দেওয়ার পক্ষে ভাল তবে এটি আপনার ব্যবসায়ের যুক্তি তৈরির পক্ষে খুব ভাল ভিত্তি নয়। আপনি যদি getState()
শর্তসাপেক্ষে বিভিন্ন ক্রিয়া প্রেরণের জন্য ব্যবহার করেন তবে পরিবর্তে ব্যবসায়িক যুক্তিটিকে হ্রাসকারীদের মধ্যে রাখার বিষয়টি বিবেচনা করুন।
পরবর্তী পদক্ষেপ
থুনস কীভাবে কাজ করে সে সম্পর্কে এখন আপনার একটি প্রাথমিক স্বীকৃতি, Redux async উদাহরণ যা সেগুলি ব্যবহার করে তা পরীক্ষা করে দেখুন।
আপনি এমন অনেকগুলি উদাহরণ খুঁজে পেতে পারেন যাতে থাঙ্কস প্রতিশ্রুতি দেয়। এটি প্রয়োজন হয় না তবে খুব সুবিধাজনক হতে পারে। রেডাক্স আপনি কী কাটা থেকে ফিরে আসবেন তা যত্ন করে না, তবে এটি আপনাকে এর থেকে ফেরতের মান দেয় dispatch()
। এ কারণেই আপনি কোনও শঙ্কার কাছ থেকে কোনও প্রতিশ্রুতি ফিরিয়ে আনতে পারেন এবং কল করে এটি সম্পন্ন হওয়ার জন্য অপেক্ষা করতে পারেন dispatch(someThunkReturningPromise()).then(...)
।
আপনি জটিল থংক অ্যাকশন নির্মাতাকে কয়েকটি ছোট ছোট থান অ্যাকশন নির্মাতাদের মধ্যেও বিভক্ত করতে পারেন। dispatch
Thunks দ্বারা উপলব্ধ পদ্ধতি নিজেই thunks গ্রহণ করতে পারে, তাই আপনি প্যাটার্ন যাও recursively আবেদন করতে পারেন। আবার, এটি প্রতিশ্রুতিগুলির সাথে সর্বোত্তম কাজ করে কারণ আপনি তার উপরে অ্যাসিনক্রোনাস নিয়ন্ত্রণ প্রবাহকে প্রয়োগ করতে পারেন।
কিছু অ্যাপ্লিকেশানের জন্য, আপনি নিজেকে এমন পরিস্থিতিতে খুঁজে পেতে পারেন যেখানে আপনার অ্যাসিনক্রোনাস নিয়ন্ত্রণ প্রবাহের প্রয়োজনীয়তা থাঙ্কস দিয়ে প্রকাশ করা খুব জটিল। উদাহরণস্বরূপ, ব্যর্থ অনুরোধগুলির পুনরায় চেষ্টা করা, টোকেনগুলি দিয়ে পুনরায় অনুমোদনের প্রবাহ বা এই ধরণের লেখার সময় একটি ধাপে ধাপে অনবোর্ডিং খুব ভার্জোজ এবং ত্রুটি-প্রবণ হতে পারে। এই ক্ষেত্রে, আপনি আরও উন্নত অ্যাসিনক্রোনাস নিয়ন্ত্রণ প্রবাহ সমাধানগুলি যেমন Redux সাগা বা রেডাক্স লুপটি দেখতে চাইতে পারেন । এগুলি মূল্যায়ন করুন, আপনার প্রয়োজনগুলির সাথে প্রাসঙ্গিক উদাহরণগুলির তুলনা করুন এবং আপনার সবচেয়ে পছন্দ হওয়া পছন্দটি চয়ন করুন।
অবশেষে, আপনার যদি সত্যিকারের প্রয়োজন না থাকে তবে (থঙ্ক সহ) কিছু ব্যবহার করবেন না। মনে রাখবেন যে প্রয়োজনীয়তার উপর নির্ভর করে আপনার সমাধানটি তত সহজ দেখায়
store.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
store.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)
আপনি কেন এমনটি করছেন তা না জানলে এটি ঘামবেন না।
redux-saga
আপনি থঙ্কস থেকে আরও ভাল কিছু চাইলে আমার ভিত্তিক উত্তরটি পরীক্ষা করতে ভুলবেন না । দেরিতে উত্তর যাতে এটি প্রদর্শিত হওয়ার আগে আপনাকে দীর্ঘ সময় স্ক্রোল করতে হবে :) এর অর্থ এটি পড়ার মতো নয়। এখানে একটি শর্টকাট: stackoverflow.com/a/38574266/82609