කල් ඉකුත් වීමක් සමඟ Redux ක්‍රියාවක් යවන්නේ කෙසේද?


916

මගේ යෙදුමේ දැනුම් දීමේ තත්වය යාවත්කාලීන කරන ක්‍රියාවක් මා සතුව ඇත. සාමාන්‍යයෙන්, මෙම දැනුම්දීම කිසියම් ආකාරයක දෝෂයක් හෝ තොරතුරු වනු ඇත. තත්පර 5 කට පසුව මට තවත් ක්‍රියාවක් යැවීමට අවශ්‍ය වන අතර එය දැනුම් දීමේ තත්වය ආරම්භක තත්වයට ගෙන එනු ඇත, එබැවින් දැනුම්දීමක් නොමැත. තත්පර 5 කට පසු දැනුම්දීම් ස්වයංක්‍රීයව අතුරුදහන් වන තැන ක්‍රියාකාරීත්වය සැපයීම මෙයට ප්‍රධාන හේතුවයි.

setTimeoutවෙනත් ක්‍රියාවක් භාවිතා කිරීමට සහ ආපසු ලබා දීමට මට වාසනාවක් නොතිබූ අතර මෙය අන්තර්ජාලය හරහා සිදු කරන්නේ කෙසේදැයි සොයාගත නොහැක. එබැවින් ඕනෑම උපදෙසක් පිළිගනු ලැබේ.


30
redux-sagaඔබට වඩා හොඳ යමක් අවශ්‍ය නම් මගේ පදනම් පිළිතුර පරීක්ෂා කිරීමට අමතක නොකරන්න . ප්‍රමාද පිළිතුර නිසා එය දිස්වීමට පෙර ඔබට බොහෝ වේලාවක් අනුචලනය කළ යුතුය :) එයින් කියවෙන්නේ එය කියවීම වටී නැති බවයි. මෙන්න කෙටිමඟක්: stackoverflow.com/a/38574266/82609
සෙබස්තියන්

5
ඔබ සකසන සෑම අවස්ථාවකම සංරචකයේ පැහැදිලි ටයිම out ට් භාවිතයෙන් ටයිමරය ඉවත් කිරීමට අමතක නොකරන්න
හේමද්‍රි දසාරි

2
redux-saga සිසිල් නමුත් උත්පාදක ක්‍රියාකාරිත්වයන්ගෙන් ටයිප් කළ ප්‍රතිචාර සඳහා ඔවුන්ට සහය නොමැති බව පෙනේ. ඔබ ප්‍රතික්‍රියා සමඟ යතුරු ලියනය භාවිතා කරන්නේ නම් වැදගත් විය හැකිය.
ක්‍රිස්ටියන් රමිරෙස්

Answers:


2672

ඇද වැටෙනු එපා පුස්තකාල සියල්ල ඉටු කරන ආකාරය නියම කළ යුතු හිතන උගුලක් . ඔබට ජාවාස්ක්‍රිප්ට් හි කල් ඉකුත් වීමක් සමඟ යමක් කිරීමට අවශ්‍ය නම්, ඔබ භාවිතා කළ setTimeoutයුතුය. Redux ක්‍රියා වෙනස් විය යුතු බවට කිසිදු හේතුවක් නැත.

Redux කරයි අසමමුහුර්ත දේවල් සමඟ ගනුදෙනු කිරීමේ විකල්ප ක්‍රම කිහිපයක් ඉදිරිපත් කරයි, නමුත් ඔබ ඒවා භාවිතා කළ යුත්තේ ඔබ ඕනෑවට වඩා කේත පුනරාවර්තනය කරන බව දැනගත් විට පමණි. ඔබට මෙම ගැටළුව නොමැති නම්, භාෂාව ඉදිරිපත් කරන දේ භාවිතා කර සරලම විසඳුම සඳහා යන්න.

අසින්ක් කේත පේළිය ලිවීම

මෙය බොහෝ දුරට සරලම ක්‍රමයයි. මෙහි Redux සඳහා විශේෂිත කිසිවක් නොමැත.

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)

මෙතෙක් අපි කිසිදු මිඩ්ල්වෙයාර් හෝ වෙනත් උසස් සංකල්පයක් භාවිතා කර නොමැත.

අසින්ක් ක්‍රියාකාරී නිර්මාතෘ උපුටා ගැනීම

ඉහත ප්‍රවේශය සරල අවස්ථාවන්හිදී හොඳින් ක්‍රියාත්මක වන නමුත් එයට ගැටළු කිහිපයක් ඇති බව ඔබට පෙනී යනු ඇත:

  • ඔබට දැනුම් දීමක් පෙන්වීමට අවශ්‍ය ඕනෑම තැනක මෙම තර්කනය අනුපිටපත් කිරීමට එය බල කරයි.
  • දැනුම්දීම්වල හැඳුනුම්පත් නොමැති බැවින් ඔබ දැනුම්දීම් දෙකක් වේගයෙන් පෙන්වන්නේ නම් ඔබට ධාවන තත්වයක් ඇත. පළමු කල් ඉකුත්වීම අවසන් වූ විට, එය යවනු ලැබේ 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.')    

මෙය තර්කනයේ අනුපිටපත් කිරීමේ ගැටළු විසඳන අතර ජාතියේ තත්වයන්ගෙන් අපව ගලවා ගනී.

Thunk Middleware

සරල යෙදුම් සඳහා, ප්රවේශය ප්රමාණවත් විය යුතුය. මිඩ්ල්වෙයාර් ගැන ඔබ සතුටු වන්නේ නම් ඒ ගැන කරදර නොවන්න.

කෙසේ වෙතත්, විශාල යෙදුම් වල, ඔබට එය වටා යම් යම් අපහසුතා ඇති විය හැකිය.

නිදසුනක් වශයෙන්, අප පසුකර යාම අවාසනාවක් සේ පෙනේ dispatch. මෙමඟින් බහාලුම් සහ ඉදිරිපත් කිරීමේ සංරචක වෙන් කිරීම උපක්‍රමශීලී වේ. මන්දයත් රෙඩක්ස් ක්‍රියාවන් ඉහත ආකාරයට සමමුහුර්තව යවන ඕනෑම අංගයක් dispatchමුක්කු ලෙස පිළිගත යුතු බැවින් එය තවදුරටත් සම්මත කළ හැකිය. ඔබට ක්‍රියා නිර්මාපකයින් connect()තවදුරටත් බැඳ තැබිය නොහැක showNotificationWithTimeout(). එය Redux ක්‍රියාවක් ලබා නොදේ.

ඊට අමතරව, සමමුහුර්ත ක්‍රියාකාරී නිර්මාපකයින් කැමති showNotification()සහ අසමමුහුර්ත උදව්කරුවන් කැමති කුමන කාර්යයන්දැයි මතක තබා ගැනීම අමුතු දෙයක් විය හැකිය showNotificationWithTimeout(). ඔබ ඒවා වෙනස් ලෙස භාවිතා කළ යුතු අතර ඒවා එකිනෙකා සමඟ වරදවා වටහා නොගැනීමට වගබලා ගන්න.

සහායක ශ්‍රිතයක් සඳහා මෙම රටාව “නීත්‍යානුකූල” කිරීමට ක්‍රමයක් සෙවීමේdispatch අභිප්‍රේරණය මෙය වූ අතර , සම්පූර්ණයෙන්ම වෙනස් ක්‍රියාකාරිත්වයන්ට වඩා සාමාන්‍ය ක්‍රියාකාරී නිර්මාණකරුවන්ගේ විශේෂ අවස්ථාවක් ලෙස සමමුහුර්ත ක්‍රියාකාරී නිර්මාණකරුවන් “දැකීමට” රෙඩක්ස් හට උදව් කරයි.

ඔබ තවමත් අප සමඟ සිටී නම් සහ ඔබගේ යෙදුමේ ගැටලුවක් ලෙස ඔබ හඳුනා ගන්නේ නම්, Redux Thunk middleware භාවිතා කිරීමට ඔබව සාදරයෙන් පිළිගනිමු .

සාරාංශයක් තුළ, ඇත්ත වශයෙන්ම ක්‍රියාකාරී වන විශේෂ ක්‍රියා හඳුනා ගැනීමට Redux Thunk Redux හට උගන්වයි:

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()සාමාන්‍ය Redux ක්‍රියාකාරී නිර්මාපකයෙකු ලෙස ප්‍රකාශ කිරීමට අපට ඉඩ දෙයි :

// 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.

කෙසේ වෙතත් මෙය මුල් අනුවාදයට වඩා අමුතුයි! ඇයි අපි ඒ පැත්තට ගියේ?

මම කලින් ඔබට කී දේ නිසා. Redux Thunk middleware සක්‍රීය කර ඇත්නම්, ඔබ ක්‍රියාකාරී වස්තුවක් වෙනුවට ශ්‍රිතයක් යැවීමට උත්සාහ කරන ඕනෑම වේලාවක, මිඩ්ල්වෙයාර් එම ශ්‍රිතය dispatchක්‍රමවේදය සමඟ පළමු තර්කය ලෙස හඳුන්වනු ඇත .

එබැවින් අපට ඒ වෙනුවට මෙය කළ හැකිය:

// component.js
this.props.dispatch(showNotificationWithTimeout('You just logged in.'))

අවසාන වශයෙන්, අසමමුහුර්ත ක්‍රියාවක් යැවීම (සැබවින්ම, ක්‍රියා මාලාවක්) එක් ක්‍රියාවක් සමමුහුර්තව සංරචකයට යැවීමට වඩා වෙනස් නොවේ. යම් දෙයක් සමමුහුර්තව හෝ සමමුහුර්තව සිදුවන්නේද යන්න සංරචක නොසලකන හෙයින් එය හොඳයි. අපි එය වියුක්ත කළා.

එවැනි “විශේෂ” ක්‍රියාකාරී නිර්මාණකරුවන් හඳුනා ගැනීමට අපි රෙඩක්ස් “ඉගැන්වූ” බැවින් (අපි ඔවුන්ව මෝඩ ක්‍රියාකාරී නිර්මාණකරුවන් ලෙස හඳුන්වන්නෙමු ), දැන් අපට නිත්‍ය ක්‍රියාකාරී නිර්මාණකරුවන් භාවිතා කරන ඕනෑම ස්ථානයක ඒවා භාවිතා කළ හැකිය. උදාහරණයක් ලෙස, අපට ඒවා භාවිතා කළ හැකිය 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)

තන්ක්ස් වල රාජ්ය කියවීම

සාමාන්‍යයෙන් ඔබේ අඩු කරන්නන්ගේ ඊළඟ තත්වය තීරණය කිරීම සඳහා ව්‍යාපාර තර්කනය අඩංගු වේ. කෙසේ වෙතත්, අඩු කරන්නන් ක්‍රියා කරන්නේ පිටත් කිරීමෙන් පසුව පමණි. ඔබ ක්‍රියාකාරී ක්‍රියාකාරී නිර්මාපකයෙකු තුළ අතුරු ආබාධයක් (API එකක් ඇමතීම වැනි) ඇත්නම් සහ යම් කොන්දේසියක් යටතේ එය වළක්වා ගැනීමට ඔබට අවශ්‍ය නම් කුමක් කළ යුතුද?

තණ්ඩ මිඩ්ල්වෙයාර් භාවිතා නොකර, ඔබ මෙම පරීක්‍ෂණය සංරචකය තුළ සිදු කරයි:

// component.js
if (this.props.areNotificationsEnabled) {
  showNotificationWithTimeout(this.props.dispatch, 'You just logged in.')
}

කෙසේ වෙතත්, ක්‍රියාකාරී නිර්මාණකරුවෙකු උපුටා ගැනීමේ කාරණය වූයේ මෙම පුනරාවර්තන තර්කනය බොහෝ සංරචක හරහා කේන්ද්‍රගත කිරීමයි. වාසනාවකට මෙන්, Redux වෙළඳසැලේ වත්මන් තත්වය කියවීමට Redux Thunk ඔබට ක්‍රමයක් සපයයි . ඊට අමතරව dispatch, එය getStateඔබගේ ක්‍රියාකාරී ක්‍රියාකාරී නිර්මාතෘ වෙතින් ඔබ ආපසු එන ශ්‍රිතයේ දෙවන තර්කය ලෙසද ගමන් කරයි . මෙමඟින් ගබඩාවේ වත්මන් තත්වය කියවීමට මාපටැඟිල්ලට ඉඩ දෙයි.

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 උදාහරණය බලන්න .

පොරොන්දම් ආපසු ලබා දෙන බොහෝ උදාහරණ ඔබට සොයාගත හැකිය. මෙය අවශ්‍ය නොවන නමුත් ඉතා පහසු විය හැකිය. Redux ඔබ මෝඩයෙකුගෙන් ආපසු එන්නේ කුමක් දැයි ගණන් ගන්නේ නැත, නමුත් එය ඔබට එහි ප්‍රතිලාභ වටිනාකම ලබා දෙයි dispatch(). මේ නිසා ඔබට පොරොන්දුවක් ආපසු ලබා දිය හැකි අතර ඇමතුමෙන් එය සම්පූර්ණ වන තෙක් බලා සිටින්න dispatch(someThunkReturningPromise()).then(...).

ඔබට සංකීර්ණ thunk action creators කුඩා thunk action creators කිහිපයකට බෙදිය හැකිය. මෙම dispatchඔබ ඇත්තෙන් වෙනසට භාජනය රටාව ඉල්ලුම් කළ හැකි නිසා thunks විසින් සපයන ක්රමය, ම thunks භාර කළ හැකිය. නැවතත්, මෙය පොරොන්දු සමඟ වඩාත් හොඳින් ක්‍රියාත්මක වන්නේ ඔබට ඒ මත අසමමුහුර්ත පාලන ප්‍රවාහයක් ක්‍රියාත්මක කළ හැකි බැවිනි.

සමහර යෙදුම් සඳහා, ඔබේ අසමමුහුර්ත පාලන ප්‍රවාහ අවශ්‍යතා තන්ක සමඟ ප්‍රකාශ කළ නොහැකි තරම් සංකීර්ණ තත්වයකට ඔබ පත්විය හැකිය. නිදසුනක් ලෙස, අසාර්ථක ඉල්ලීම් නැවත උත්සාහ කිරීම, ටෝකන සමඟ නැවත බලය පැවරීම හෝ පියවරෙන් පියවර යතුරු පුවරුව මේ ආකාරයෙන් ලිවීමේදී වාචික හා දෝෂ සහිත විය හැකිය. මෙම අවස්ථාවේදී, ඔබට Redux Saga හෝ Redux Loop වැනි වඩා දියුණු අසමමුහුර්ත පාලන ප්‍රවාහ විසඳුම් දෙස බැලීමට අවශ්‍ය විය හැකිය . ඒවා ඇගයීමට ලක් කරන්න, ඔබේ අවශ්‍යතාවන්ට අදාළ උදාහරණ සංසන්දනය කර ඔබ වඩාත්ම කැමති දේ තෝරා ගන්න.

අවසාන වශයෙන්, ඔබට ඒවා සඳහා අව්‍යාජ අවශ්‍යතාවයක් නොමැති නම් (කටු ඇතුළු) කිසිවක් භාවිතා නොකරන්න. අවශ්‍යතා මත පදනම්ව, ඔබේ විසඳුම තරම් සරල බව මතක තබා ගන්න

store.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
  store.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)

ඔබ මෙය කරන්නේ ඇයි දැයි ඔබ දන්නේ නැත්නම් එය දහඩිය දමන්න එපා.


27
අසින්ක් ක්‍රියා පොදු ගැටලුවකට එතරම් සරල හා අලංකාර විසඳුමක් සේ පෙනේ. මිඩ්ල්වෙයාර් අවශ්‍යතාවයකින් තොරව රෙඩෙක්ස් කිරීම සඳහා ඔවුන්ට සහාය නොදක්වන්නේ ඇයි? මෙම පිළිතුර වඩාත් සංක්ෂිප්ත විය හැකිය.
ෆිල් මැන්ඩර්

84
H ෆිල්මාන්ඩර් github.com/raisemarketplace/redux-loop හෝ github.com/yelouafi/redux-saga වැනි විකල්ප රටා බොහොමයක් ඇති බැවින් ඒවා (වඩා වැඩි නොවේ) අලංකාරයි . Redux යනු පහත් මට්ටමේ මෙවලමකි. ඔබට කැමති සුපර්සෙට් එකක් සාදා එය වෙන වෙනම බෙදා හැරිය හැක.
ඩෑන් ආබ්‍රමොව්

16
ඔබට මෙය පැහැදිලි කළ හැකිද: * ව්‍යාපාර තර්කනය අඩු කරන්නන්ට ඇතුළත් කිරීම ගැන සලකා බලන්න *, එයින් අදහස් කරන්නේ මා යම් ක්‍රියාවක් යැවිය යුතු බවත්, පසුව මගේ තත්වය අනුව යැවිය යුතු තවත් ක්‍රියාමාර්ග මොනවාද යන්න අඩු කරන්නා තුළ තීරණය කළ යුතුද? මගේ ප්‍රශ්නය නම්, මම වෙනත් ක්‍රියා සෘජුවම මගේ අඩු කරන්නා වෙත යවනවාද, එසේ නොවේ නම් මම ඒවා කොහෙන්ද යවන්නේ?
froginvasion

26
මෙම වාක්‍යය අදාළ වන්නේ සමමුහුර්ත නඩුවට පමණි. උදාහරණයක් ලෙස ඔබ ලියන්නේ නම් if (cond) dispatch({ type: 'A' }) else dispatch({ type: 'B' })සමහර විට ඔබ එය කළ යුතු අතර වර්තමාන තත්වය dispatch({ type: 'C', something: cond })මත පදනම්ව අඩු කරන්නන්ගේ ක්‍රියාව නොසලකා හැරිය යුතුය action.something.
ඩෑන් ආබ්‍රමොව්

32
An ඩන් අබ්‍රමොව් ඔබ මේ සඳහා මගේ අභිප්‍රාය ලබා ගත්තේ "ඔබට මෙම ගැටලුව නොමැති නම්, භාෂාව ඉදිරිපත් කරන දේ භාවිතා කර සරලම විසඳුම සඳහා යන්න." එය ලිව්වේ කවුදැයි මට වැටහුණේ පසුව පමණි!
මැට් ලේසි

195

Redux-saga භාවිතා කිරීම

ඩෑන් ආබ්‍රමොව් පැවසූ පරිදි, ඔබේ අසින්ක් කේතය පාලනය කිරීමට ඔබට අවශ්‍ය නම්, ඔබට රෙඩක්ස්-සාගා දෙස බැලිය හැකිය .

මෙම පිළිතුර සරල උදාහරණයකි, ඔබේ යෙදුමට රීඩක්ස්-සාගා ප්‍රයෝජනවත් විය හැක්කේ මන්ද යන්න පිළිබඳ වඩා හොඳ පැහැදිලි කිරීම් අවශ්‍ය නම්, මෙම අනෙක් පිළිතුර පරීක්ෂා කරන්න .

සාමාන්‍ය අදහස නම්, Redux-saga විසින් ES6 උත්පාදක පරිවර්තකයක් ඉදිරිපත් කරන අතර එය සමමුහුර්ත කේතයක් ලෙස පෙනෙන අසින්ක් කේත පහසුවෙන් ලිවීමට ඔබට ඉඩ සලසයි (Redux-saga හි ලූප අතරේ ඔබ බොහෝ විට අනන්තය සොයා ගන්නේ මේ නිසාය). කෙසේ හෝ Redux-saga ජාවාස්ක්‍රිප්ට් තුළ කෙලින්ම තමන්ගේම භාෂාවක් ගොඩනගමින් සිටී. Redux-saga මුලදී ඉගෙන ගැනීමට ටිකක් අපහසු විය හැකිය, මන්ද ඔබට ජනක යන්ත්‍ර පිළිබඳ මූලික අවබෝධයක් අවශ්‍ය වන අතරම Redux-saga විසින් ඉදිරිපත් කරන භාෂාවද තේරුම් ගත යුතුය.

රෙඩක්ස්-සාගා මුදුනේ මා විසින් සාදන ලද දැනුම්දීම් පද්ධතිය විස්තර කිරීමට මම මෙහි උත්සාහ කරමි. මෙම උදාහරණය දැනට නිෂ්පාදනයේ ක්‍රියාත්මක වේ.

උසස් දැනුම්දීම් පද්ධති පිරිවිතර

  • ප්‍රදර්ශනය කිරීම සඳහා ඔබට දැනුම් දීමක් ඉල්ලා සිටිය හැකිය
  • සැඟවීමට ඔබට දැනුම් දීමක් ඉල්ලා සිටිය හැකිය
  • දැනුම්දීමක් තත්පර 4 කට වඩා ප්‍රදර්ශනය නොකළ යුතුය
  • එකවර විවිධ දැනුම්දීම් පෙන්විය හැකිය
  • එකවර දැනුම්දීම් 3 කට වඩා පෙන්විය නොහැක
  • දැනටමත් ප්‍රදර්ශනය කර ඇති දැනුම්දීම් 3 ක් තිබියදී දැනුම් දීමක් ඉල්ලා සිටී නම්, පෝලිම් / කල් දමන්න.

ප්‍රති ult ලය

මගේ නිෂ්පාදන යෙදුම වන Stample.co හි තිර රුව

ටෝස්ට්

කේතය

මෙන්න මම දැනුම්දීම a ලෙස නම් කළ toastනමුත් මෙය නම් කිරීමේ විස්තරයකි.

function* toastSaga() {

    // Some config constants
    const MaxToasts = 3;
    const ToastDisplayTime = 4000;


    // Local generator state: you can put this state in Redux store
    // if it's really important to you, in my case it's not really
    let pendingToasts = []; // A queue of toasts waiting to be displayed
    let activeToasts = []; // Toasts currently displayed


    // Trigger the display of a toast for 4 seconds
    function* displayToast(toast) {
        if ( activeToasts.length >= MaxToasts ) {
            throw new Error("can't display more than " + MaxToasts + " at the same time");
        }
        activeToasts = [...activeToasts,toast]; // Add to active toasts
        yield put(events.toastDisplayed(toast)); // Display the toast (put means dispatch)
        yield call(delay,ToastDisplayTime); // Wait 4 seconds
        yield put(events.toastHidden(toast)); // Hide the toast
        activeToasts = _.without(activeToasts,toast); // Remove from active toasts
    }

    // Everytime we receive a toast display request, we put that request in the queue
    function* toastRequestsWatcher() {
        while ( true ) {
            // Take means the saga will block until TOAST_DISPLAY_REQUESTED action is dispatched
            const event = yield take(Names.TOAST_DISPLAY_REQUESTED);
            const newToast = event.data.toastData;
            pendingToasts = [...pendingToasts,newToast];
        }
    }


    // We try to read the queued toasts periodically and display a toast if it's a good time to do so...
    function* toastScheduler() {
        while ( true ) {
            const canDisplayToast = activeToasts.length < MaxToasts && pendingToasts.length > 0;
            if ( canDisplayToast ) {
                // We display the first pending toast of the queue
                const [firstToast,...remainingToasts] = pendingToasts;
                pendingToasts = remainingToasts;
                // Fork means we are creating a subprocess that will handle the display of a single toast
                yield fork(displayToast,firstToast);
                // Add little delay so that 2 concurrent toast requests aren't display at the same time
                yield call(delay,300);
            }
            else {
                yield call(delay,50);
            }
        }
    }

    // This toast saga is a composition of 2 smaller "sub-sagas" (we could also have used fork/spawn effects here, the difference is quite subtile: it depends if you want toastSaga to block)
    yield [
        call(toastRequestsWatcher),
        call(toastScheduler)
    ]
}

සහ අඩු කරන්නා:

const reducer = (state = [],event) => {
    switch (event.name) {
        case Names.TOAST_DISPLAYED:
            return [...state,event.data.toastData];
        case Names.TOAST_HIDDEN:
            return _.without(state,event.data.toastData);
        default:
            return state;
    }
};

භාවිතය

ඔබට සරලවම TOAST_DISPLAY_REQUESTEDසිදුවීම් යැවිය හැකිය . ඔබ ඉල්ලීම් 4 ක් යවන්නේ නම්, දැනුම්දීම් 3 ක් පමණක් දර්ශනය වන අතර, 1 වන දැනුම්දීම අතුරුදහන් වූ පසු 4 වන අවස්ථාව මඳක් පසුව දිස්වනු ඇත.

TOAST_DISPLAY_REQUESTEDJSX වෙතින් පිටත් කර යැවීමට මම විශේෂයෙන් නිර්දේශ නොකරන බව සලකන්න . ඔබ දැනටමත් පවතින යෙදුම් සිදුවීම් වලට සවන් දෙන තවත් කතන්දරයක් එකතු කර, පසුව යවන්න TOAST_DISPLAY_REQUESTED: දැනුම්දීම අවුලුවන ඔබේ සංරචකය, දැනුම්දීම් පද්ධතියට තදින් සම්බන්ධ කිරීම අවශ්‍ය නොවේ.

නිගමනය

මගේ කේතය පරිපූර්ණ නොවන නමුත් මාස 0 ක් තිස්සේ දෝෂ 0 ක් සමඟ නිෂ්පාදනයේ යෙදේ. Redux-saga සහ උත්පාදක යන්ත්ර මුලින් මඳක් අමාරු නමුත් ඔබ ඒවා තේරුම් ගත් පසු මේ ආකාරයේ පද්ධතියක් සෑදීම පහසුය.

වඩාත් සංකීර්ණ නීති ක්‍රියාත්මක කිරීම ඊටත් වඩා පහසු ය, වැනි:

  • බොහෝ දැනුම්දීම් "පෝලිම්" ඇති විට, එක් එක් දැනුම්දීම සඳහා අඩු දර්ශන කාලයක් ලබා දෙන්න එවිට පෝලිම් ප්‍රමාණය වේගයෙන් අඩු විය හැකිය.
  • කවුළු ප්‍රමාණයේ වෙනස්කම් හඳුනාගෙන, ඒ අනුව පෙන්වන උපරිම දැනුම්දීම් සංඛ්‍යාව ඒ අනුව වෙනස් කරන්න (නිදසුනක් ලෙස, ඩෙස්ක්ටොප් = 3, දුරකථන ආලේඛ්‍ය චිත්‍රය = 2, දුරකථන භූ දර්ශනය = 1)

අවංකවම, වාසනාව මේ ආකාරයේ දේවල් නිසි ලෙස ක්‍රියාත්මක කිරීම.

රෙඩක්ස්-සාගා වලට බෙහෙවින් සමාන වන රෙඩක්ස්-නිරීක්ෂණය කළ හැකි දේ සමඟ ඔබට හරියටම එකම දේ කළ හැකි බව සලකන්න . එය බොහෝ දුරට සමාන වන අතර උත්පාදක යන්ත්ර සහ RxJS අතර රසයේ කාරණයකි.


19
මේ වගේ ව්‍යාපාරික තර්කනය සඳහා සාගා අතුරු ආබාධ පුස්තකාලය භාවිතා කිරීම ගැන මට මීට වඩා එකඟ විය නොහැකි නිසා ප්‍රශ්නය ඇසූ විට ඔබේ පිළිතුර මීට පෙර ලැබෙනු ඇතැයි මම ප්‍රාර්ථනා කරමි. අඩු කරන්නන් සහ ක්‍රියාකාරී නිර්මාපකයින් රාජ්‍ය සංක්‍රාන්තිය සඳහා වේ. කාර්ය ප්‍රවාහයන් රාජ්‍ය සංක්‍රාන්ති ශ්‍රිතවලට සමාන නොවේ. කාර්ය ප්‍රවාහ සංක්‍රාන්ති හරහා ගමන් කරයි, නමුත් ඒවා සංක්‍රාන්ති නොවේ. Redux + React හි මෙය තනිවම නොමැති වීම - Redux Saga මෙතරම් ප්‍රයෝජනවත් වන්නේ මේ නිසාය.
ඇටිකස්

4
ස්තූතියි, මෙම හේතූන් නිසා රෙඩක්ස්-සාගා ජනප්‍රිය කිරීමට මම උපරිම උත්සාහයක් දරමි :) ඉතා සුළු පිරිසක් සිතන්නේ දැනට රීඩක්ස්-සාගා යනු තන්ක සඳහා ආදේශකයක් පමණක් වන අතර රෙඩක්ස්-සාගා සංකීර්ණ හා විසංයෝජනය කරන ලද කාර්ය ප්‍රවාහයන් සක්‍රීය කරන්නේ කෙසේදැයි නොපෙනේ
සෙබස්තියන් ලෝර්බර්

1
හරියටම. ක්‍රියා සහ අඩු කරන්නන් සියල්ල රාජ්‍ය යන්ත්‍රයේ කොටසකි. සමහර විට, සංකීර්ණ කාර්ය ප්‍රවාහ සඳහා, රාජ්‍ය යන්ත්‍රයේ directly ජුවම කොටසක් නොවන රාජ්‍ය යන්ත්‍රය සැකසීමට ඔබට වෙනත් යමක් අවශ්‍ය වේ!
ඇටිකස්

2
ක්‍රියා: සංක්‍රාන්ති තත්වයට ගෙවීම් / සිදුවීම්. අඩු කරන්නන්: රාජ්‍ය සංක්‍රාන්ති කාර්යයන්. සංරචක: තත්වය පිළිබිඹු කරන පරිශීලක අතුරුමුහුණත්. නමුත් එක් ප්‍රධාන කොටසක් අතුරුදහන් වී ඇත - ඊළඟට සිදු කළ යුත්තේ කුමන සංක්‍රාන්තියද යන්න තීරණය කරන සියල්ලන්ටම ඔවුන්ගේම තර්කනයක් ඇති බොහෝ සංක්‍රාන්ති ක්‍රියාවලිය ඔබ කළමනාකරණය කරන්නේ කෙසේද? රෙඩක්ස් සාගා!
ඇටිකස්

2
rmrbrdo ඔබ මගේ පිළිතුර හොඳින් කියවා බැලුවහොත් දැනුම් දීමේ වේලාව සැබවින්ම හසුරුවා ඇති බව ඔබට පෙනෙනු ඇත yield call(delay,timeoutValue);: එය එකම API නොවේ, නමුත් එය එකම බලපෑමක් ඇති කරයි
සෙබස්තියන් ලෝර්බර්

26

නියැදි ව්‍යාපෘති සහිත ගබඩාවක්

දැනට නියැදි ව්‍යාපෘති හතරක් ඇත:

  1. අසින්ක් කේත පේළිය ලිවීම
  2. අසින්ක් ක්‍රියාකාරී නිර්මාතෘ උපුටා ගැනීම
  3. Redux Thunk භාවිතා කරන්න
  4. Redux Saga භාවිතා කරන්න

පිළිගත් පිළිතුර නියමයි.

නමුත් යමක් මග හැරී ඇත:

  1. ධාවනය කළ හැකි නියැදි ව්‍යාපෘති නොමැත, සමහර කේත ස්නිපෙට් පමණි.
  2. වෙනත් විකල්ප සඳහා නියැදි කේතයක් නොමැත, වැනි:
    1. රෙඩක්ස් සාගා

එබැවින් නැතිවූ දේවල් එකතු කිරීම සඳහා මම හෙලෝ අසින්ක් ගබඩාව නිර්මාණය කළෙමි :

  1. ක්‍රියාත්මක කළ හැකි ව්‍යාපෘති. ඔබට ඒවා වෙනස් කිරීමකින් තොරව බාගත කර ක්‍රියාත්මක කළ හැකිය.
  2. තවත් විකල්ප සඳහා නියැදි කේතය සපයන්න:

රෙඩක්ස් සාගා

පිළිගත් පිළිතුර දැනටමත් Async Code Inline, Async Action Generator සහ Redux Thunk සඳහා නියැදි කේත ස්නිපෙට් සපයයි. සම්පූර්ණත්වය සඳහා, මම Redux Saga සඳහා කේත ස්නිපෙට් ලබා දෙමි:

// actions.js

export const showNotification = (id, text) => {
  return { type: 'SHOW_NOTIFICATION', id, text }
}

export const hideNotification = (id) => {
  return { type: 'HIDE_NOTIFICATION', id }
}

export const showNotificationWithTimeout = (text) => {
  return { type: 'SHOW_NOTIFICATION_WITH_TIMEOUT', text }
}

ක්‍රියා සරල හා පිරිසිදු ය.

// component.js

import { connect } from 'react-redux'

// ...

this.props.showNotificationWithTimeout('You just logged in.')

// ...

export default connect(
  mapStateToProps,
  { showNotificationWithTimeout }
)(MyComponent)

සංරචකය සමඟ කිසිවක් විශේෂ නොවේ.

// sagas.js

import { takeEvery, delay } from 'redux-saga'
import { put } from 'redux-saga/effects'
import { showNotification, hideNotification } from './actions'

// Worker saga
let nextNotificationId = 0
function* showNotificationWithTimeout (action) {
  const id = nextNotificationId++
  yield put(showNotification(id, action.text))
  yield delay(5000)
  yield put(hideNotification(id))
}

// Watcher saga, will invoke worker saga above upon action 'SHOW_NOTIFICATION_WITH_TIMEOUT'
function* notificationSaga () {
  yield takeEvery('SHOW_NOTIFICATION_WITH_TIMEOUT', showNotificationWithTimeout)
}

export default notificationSaga

සාගා ඊඑස් 6 ජනක යන්ත්‍ර මත පදනම් වේ

// index.js

import createSagaMiddleware from 'redux-saga'
import saga from './sagas'

const sagaMiddleware = createSagaMiddleware()

const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

sagaMiddleware.run(saga)

Redux Thunk හා සසඳන විට

වාසි

  • ඔබ නැවත ඇමතුම් නිරයට නොයන්න.
  • ඔබේ අසමමුහුර්ත ප්‍රවාහ පහසුවෙන් පරීක්ෂා කළ හැකිය.
  • ඔබේ ක්‍රියාව පිරිසිදුයි.

අවාසි

  • එය සාපේක්ෂව නව වන ES6 ජනක යන්ත්‍ර මත රඳා පවතී.

ඉහත කේත ස්නිපෙට් ඔබගේ සියලු ප්‍රශ්න වලට පිළිතුරු නොදෙන්නේ නම් කරුණාකර ක්‍රියාත්මක කළ හැකි ව්‍යාපෘතිය වෙත යොමු වන්න .


24

ඔබට මෙය රීඩක්ස්-තුන්ක් සමඟ කළ හැකිය . ඒ නිසා එය රංගනයක් ලේඛනයේ මග පෙන්වීමක් setTimeout වැනි අසමකාලීක බලපෑමයි.


මිඩ්ල්වෙයාර් භාවිතා කරන විට ඉක්මන් පසු විපරම් ප්‍රශ්නයක් නම්, applyMiddleware(ReduxPromise, thunk)(createStore)ඔබ මිඩ්ල්වෙයාර් කිහිපයක් (කෝමා වලින් වෙන් කර තිබේද?) එකතු කරන්නේ කෙසේද යන්නයි.
ඉල්ජා

1
L ඉල්ජා මෙය ක්‍රියාත්මක විය යුතුය:const store = createStore(reducer, applyMiddleware([ReduxPromise, thunk]));
geniuscarrier

23

SAM රටාව දෙස බැලීමට ද මම නිර්දේශ කරමි .

ආකෘතිය යාවත්කාලීන වූ පසු “දැනුම්දීම් තත්පර 5 කට පසු ස්වයංක්‍රීයව අතුරුදහන් වේ” වැනි (ස්වයංක්‍රීය) ක්‍රියාවන් අවුලුවන ලද “ඊළඟ ක්‍රියා-පුරෝකථනය” ඇතුළත් කිරීම සඳහා SAM රටාව යෝජනා කරයි (SAM ආකෘතිය ~ අඩුකිරීමේ තත්වය + ගබඩාව).

රටාව එකවර ක්‍රියාවන් හා ආකෘති විකෘති අනුපිළිවෙලට අනුබල දෙයි, මන්ද ආකෘතියේ “පාලන තත්වය” කුමන ක්‍රියාවන් සක්‍රීය කර ඇත්ද යන්න සහ / හෝ ඊළඟ ක්‍රියා අනාවැකිය මඟින් ස්වයංක්‍රීයව ක්‍රියාත්මක වන බැවිනි. ක්‍රියාවක් සැකසීමට පෙර පද්ධතිය කුමක් වනු ඇත්දැයි ඔබට අනාවැකි කිව නොහැක (එබැවින්) ඔබේ ඊළඟ අපේක්ෂිත ක්‍රියාවට ඉඩ දිය හැකිද / හැකි ද යන්න.

උදාහරණයක් ලෙස කේතය,

export function showNotificationWithTimeout(dispatch, text) {
  const id = nextNotificationId++
  dispatch(showNotification(id, text))

  setTimeout(() => {
    dispatch(hideNotification(id))
  }, 5000)
}

SAM සමඟ ඉඩ නොදෙනු ඇත, මන්ද සැඟවුණු දැනුම් දීමේ ක්‍රියාවක් පිටත් කර යැවිය හැකි කාරණය රඳා පවතින්නේ "showNotication: true" අගය සාර්ථකව පිළිගන්නා ආකෘතිය මත ය. එය පිළිගැනීම වලක්වන ආකෘතියේ වෙනත් කොටස් තිබිය හැකි අතර එම නිසා සැඟවුණු දැනුම් දීමේ ක්‍රියාව ආරම්භ කිරීමට කිසිදු හේතුවක් නැත.

ගබඩාවේ යාවත්කාලීනයන්ගෙන් පසුව නිසි ඊළඟ ක්‍රියාමාර්ගයක් පුරෝකථනය කිරීම සහ ආකෘතියේ නව පාලන තත්ත්වය දැනගත හැකි බව මම තරයේ නිර්දේශ කරමි. ඔබ සොයන හැසිරීම ක්‍රියාත්මක කිරීමට ආරක්ෂිතම ක්‍රමය එයයි.

ඔබට අවශ්‍ය නම් ගිටර් සමඟ අප හා සම්බන්ධ විය හැකිය. තවද එහි ඇති 'සෑම්' මෙතන ආරම්භ මඟ පෙන්වීමක් ලබා ගත හැකි ලබා .


මම මේ වන විට මතුපිට සීරීමට ලක් කර ඇත, නමුත් දැනටමත් SAM රටාවෙන් සතුටට පත්ව සිටිමි. V = S( vm( M.present( A(data) ) ), nap(M))ලස්සනයි. ඔබගේ අදහස් සහ අත්දැකීම් බෙදා ගැනීම ගැන ස්තූතියි. මම ගැඹුරට හාරන්නම්.

ස්තූතියි, ස්තූතියි! මම එය පළමු වරට ලියන විට මටත් ඒ හැඟීමම ඇති විය. මම දැන් වසරකට ආසන්න කාලයක් තිස්සේ නිෂ්පාදනය සඳහා SAM භාවිතා කර ඇති අතර, SAM ක්‍රියාත්මක කිරීම සඳහා පුස්තකාලයක් අවශ්‍ය යැයි මට හැඟුණු කාලයක් ගැන මට සිතිය නොහැකිය (vdom පවා, එය භාවිතා කළ හැක්කේ කවදාදැයි මට පෙනේ). එක් කේත පේළියක් පමණි, එපමණයි! SAM සමාවයවික කේතයක් නිපදවයි, අසින්ක් ඇමතුම් සමඟ කටයුතු කරන්නේ කෙසේද යන්න පිළිබඳ අවිනිශ්චිතතාවයක් නොමැත ... මට කාලය ගැන සිතිය නොහැක, නමුත් මා කුමක් කරන්නේද?
metaprogrammer

SAM යනු සැබෑ මෘදුකාංග ඉංජිනේරු රටාවකි (එය සමඟ ඇලෙක්සා එස්ඩීකේ නිපදවා ඇත). එය TLA + මත පදනම් වී ඇති අතර එම ඇදහිය නොහැකි කාර්යයේ බලය සෑම සංවර්ධකයෙකුටම ගෙන ඒමට උත්සාහ කරයි. SAM විසින් දශක ගණනාවක් තිස්සේ භාවිතා කර ඇති ආසන්න වශයෙන් තක්සේරු කිරීම් තුනක් නිවැරදි කරයි: - ක්‍රියාවන්ට යෙදුම් තත්වය හැසිරවිය හැකිය - පැවරුම් විකෘතියට සමාන වේ - ක්‍රමලේඛන පියවර යනු කුමක්ද යන්න පිළිබඳ නිශ්චිත අර්ථ දැක්වීමක් නොමැත (උදා: a = b * ca පියවර , 1 / read b, c 2 / compute b * c, 3 / a
ප්‍රති result ලය

21

විවිධ ජනප්‍රිය ප්‍රවේශයන් (ක්‍රියාකාරී නිර්මාපකයින්, තන්ග්ස්, සාගාස්, එපික්ස්, ප්‍රයෝග, අභිරුචි මිඩ්ල්වෙයාර්) අත්හදා බැලීමෙන් පසුව, වැඩිදියුණු වීමට ඉඩක් ඇති බව මට තවමත් හැඟී ගියේය, එබැවින් මගේ ගමන මෙම බ්ලොග් ලිපියේ ලේඛනගත කළෙමි, මගේ ව්‍යාපාර තර්කනය කොතැනට දැමිය යුතුද? ප්‍රතික්‍රියා / Redux යෙදුමක්?

මෙහි සාකච්ඡා මෙන් බොහෝ උත්සාහයන් හා සැසඳීමට මම උත්සාහ කළෙමි. අවසානයේදී එය නව පුස්තකාල නැවත හඳුන්වාදීමේ තර්කනයක් හඳුන්වාදීමට මග පෑදූ අතර එය එපික්ස්, සාගාස්, අභිරුචි මිඩ්ල්වෙයාර් වලින් ආශ්වාදයක් ලබා ගනී.

වලංගු කිරීම, සත්‍යාපනය කිරීම, බලය පැවරීම මෙන්ම අසමමුහුර්ත IO සිදු කිරීමට ක්‍රමයක් සැපයීම සඳහා ක්‍රියා බාධා කිරීමට එය ඔබට ඉඩ දෙයි.

සමහර පොදු ක්‍රියාකාරිත්වය හුදෙක් ප්‍රකාශ කිරීම කළ හැක්කේ නිශ්ක්‍රීය කිරීම, තෙරපීම, අවලංගු කිරීම සහ නවතම ඉල්ලීම (takeLatest) වෙතින් ලැබෙන ප්‍රතිචාරය පමණි. ඔබට මෙම ක්‍රියාකාරීත්වය සපයන ඔබේ කේතය රෙඩක්ස්-ලොජික් ඔතා.

එය ඔබ කැමති කෙසේ වෙතත් ඔබේ මූලික ව්‍යාපාරික තර්කනය ක්‍රියාත්මක කිරීමට ඔබව නිදහස් කරයි. ඔබට අවශ්‍ය නම් නිරීක්ෂණ හෝ ජනක යන්ත්‍ර භාවිතා කිරීමට අවශ්‍ය නැත. කාර්යයන් සහ ඇමතුම්, පොරොන්දු, අසින්ක් ශ්‍රිත (අසින්ක් / බලා සිටින්න) ආදිය භාවිතා කරන්න.

සරල 5s දැනුම්දීමක් සඳහා කේතය මෙවැන්නක් වනු ඇත:

const notificationHide = createLogic({
  // the action type that will trigger this logic
  type: 'NOTIFICATION_DISPLAY',
  
  // your business logic can be applied in several
  // execution hooks: validate, transform, process
  // We are defining our code in the process hook below
  // so it runs after the action hit reducers, hide 5s later
  process({ getState, action }, dispatch) {
    setTimeout(() => {
      dispatch({ type: 'NOTIFICATION_CLEAR' });
    }, 5000);
  }
});
    

මගේ රෙපෝ හි වඩා දියුණු දැනුම් දීමේ නිදසුනක් මා සතුව ඇති අතර එය සෙබස්තියන් ලෝර්බර් විස්තර කළ ආකාරයටම ඔබට දර්ශනය එන් අයිතමවලට සීමා කළ හැකි අතර පෝලිම් ගැසී ඇති ඕනෑම දෙයක් හරහා භ්‍රමණය විය හැකිය. රීඩක්ස්-ලොජික් දැනුම්දීම් උදාහරණය

මට විවිධාකාර ප්‍රති-තර්කානුකූල jsfiddle සජීවී උදාහරණ මෙන්ම සම්පූර්ණ උදාහරණ ඇත. මම දිගටම ලියකියවිලි සහ උදාහරණ මත වැඩ කරමි.

ඔබගේ ප්‍රතිපෝෂණ ඇසීමට මම කැමතියි.


මම ඔබේ පුස්තකාලයට කැමති බව මට විශ්වාස නැත, නමුත් මම ඔබේ ලිපියට කැමතියි! හොඳයි, මචං! අන් අයගේ කාලය ඉතිරි කර ගැනීම සඳහා ඔබ ප්‍රමාණවත් වැඩ කර ඇත.
ටයිලර් ලෝන්ග්

2
මම මෙහි ප්‍රතිනිර්මාණ -තර්කනය සඳහා නියැදි ව්‍යාපෘතියක් නිර්මාණය කළෙමි: github.com/tylerlong/hello-async/tree/master/redux-logic මම හිතන්නේ එය හොඳින් සැලසුම් කරන ලද මෘදුකාංගයක් වන අතර අනෙක් ඒවාට සාපේක්ෂව විශාල අවාසි මා දකින්නේ නැහැ විකල්ප.
ටයිලර් ලෝන්ග්

10

මෙම ප්‍රශ්නය මඳක් පැරණි බව මට වැටහී ඇති නමුත් මම නැවත විසඳුමක් හඳුන්වා දීමට යන්නේ නැවත නැවත නිරීක්ෂණය කළ හැකි අකා භාවිතා කරමිනි . එපික්.

නිල ලියකියවිලි උපුටා දක්වමින්:

නැවත නිරීක්ෂණය කළ හැකි දේ කුමක්ද?

Redux සඳහා RxJS 5 මත පදනම් වූ මිඩ්ල්වෙයාර්. අතුරු ආබාධ සහ තවත් බොහෝ දේ නිර්මාණය කිරීම සඳහා අසමමුහුර්ත ක්‍රියා රචනා කර අවලංගු කරන්න.

එපික් යනු රීඩැක්ස් නිරීක්ෂණය කළ හැකි මූලික ප්‍රාථමිකයයි.

එය ක්‍රියාවන් ප්‍රවාහයක් ගෙන ක්‍රියා ප්‍රවාහයක් ලබා දෙන ශ්‍රිතයකි. ක්‍රියාවන්, ක්‍රියාමාර්ග.

වැඩි වශයෙන් හෝ අඩු වචන වලින්, ඔබට ධාරාවක් හරහා ක්‍රියා ලබා ගන්නා ශ්‍රිතයක් නිර්මාණය කළ හැකි අතර පසුව නව ක්‍රියා ප්‍රවාහයක් ආපසු ලබා දිය හැකිය (කල් ඉකුත්වීම, ප්‍රමාදයන්, කාල පරතරයන් සහ ඉල්ලීම් වැනි පොදු අතුරු ආබාධ භාවිතා කරමින්).

මට කේතය පළ කිරීමට ඉඩ දී ඒ ගැන තව ටිකක් පැහැදිලි කරන්න

store.js

import {createStore, applyMiddleware} from 'redux'
import {createEpicMiddleware} from 'redux-observable'
import {Observable} from 'rxjs'
const NEW_NOTIFICATION = 'NEW_NOTIFICATION'
const QUIT_NOTIFICATION = 'QUIT_NOTIFICATION'
const NOTIFICATION_TIMEOUT = 2000

const initialState = ''
const rootReducer = (state = initialState, action) => {
  const {type, message} = action
  console.log(type)
  switch(type) {
    case NEW_NOTIFICATION:
      return message
    break
    case QUIT_NOTIFICATION:
      return initialState
    break
  }

  return state
}

const rootEpic = (action$) => {
  const incoming = action$.ofType(NEW_NOTIFICATION)
  const outgoing = incoming.switchMap((action) => {
    return Observable.of(quitNotification())
      .delay(NOTIFICATION_TIMEOUT)
      //.takeUntil(action$.ofType(NEW_NOTIFICATION))
  });

  return outgoing;
}

export function newNotification(message) {
  return ({type: NEW_NOTIFICATION, message})
}
export function quitNotification(message) {
  return ({type: QUIT_NOTIFICATION, message});
}

export const configureStore = () => createStore(
  rootReducer,
  applyMiddleware(createEpicMiddleware(rootEpic))
)

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {configureStore} from './store.js'
import {Provider} from 'react-redux'

const store = configureStore()

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

App.js

import React, { Component } from 'react';
import {connect} from 'react-redux'
import {newNotification} from './store.js'

class App extends Component {

  render() {
    return (
      <div className="App">
        {this.props.notificationExistance ? (<p>{this.props.notificationMessage}</p>) : ''}
        <button onClick={this.props.onNotificationRequest}>Click!</button>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    notificationExistance : state.length > 0,
    notificationMessage : state
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onNotificationRequest: () => dispatch(newNotification(new Date().toDateString()))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

මෙම ගැටළුව විසඳීම සඳහා වන ප්‍රධාන කේතය ඔබට පෙනෙන පරිදි පයි තරම් පහසුය, අනෙක් පිළිතුරු වලට වඩා වෙනස් ලෙස පෙනෙන එකම දෙය rootEpic ශ්‍රිතයයි.

ලක්ෂ්‍යය 1. සාගාස් මෙන්ම, ක්‍රියා ප්‍රවාහයක් ලබා ගන්නා සහ ක්‍රියා ප්‍රවාහයක් ලබා දෙන ඉහළ මට්ටමේ ශ්‍රිතයක් ලබා ගැනීම සඳහා ඔබ එපික්ස් ඒකාබද්ධ කළ යුතුය, එවිට ඔබට එය මිඩ්ල්වෙයාර් කර්මාන්තශාලාව සමඟ එපික්මිඩ්ල්වෙයාර් භාවිතා කළ හැකිය . අපගේ නඩුවේදී අපට අවශ්‍ය වන්නේ එකක් පමණි, එබැවින් අපට ඇත්තේ අපගේ rootEpic පමණි, එබැවින් අපට කිසිවක් ඒකාබද්ධ කිරීමට අවශ්‍ය නැත, නමුත් සත්‍යය දැන ගැනීම හොඳය.

ලක්ෂ්‍යය 2. අතුරු ආබාධ පිළිබඳ තර්කනය ගැන සැලකිලිමත් වන අපගේ rootEpic කේත පේළි 5 ක් පමණ ගත කරයි. බොහෝ දුරට ප්‍රකාශ කළ හැකි කාරණය ඇතුළුව!

ලක්ෂ්‍යය 3. රේඛාව අනුව රේඛාව

const rootEpic = (action$) => {
  // sets the incoming constant as a stream 
  // of actions with  type NEW_NOTIFICATION
  const incoming = action$.ofType(NEW_NOTIFICATION)
  // Merges the "incoming" stream with the stream resulting for each call
  // This functionality is similar to flatMap (or Promise.all in some way)
  // It creates a new stream with the values of incoming and 
  // the resulting values of the stream generated by the function passed
  // but it stops the merge when incoming gets a new value SO!,
  // in result: no quitNotification action is set in the resulting stream
  // in case there is a new alert
  const outgoing = incoming.switchMap((action) => {
    // creates of observable with the value passed 
    // (a stream with only one node)
    return Observable.of(quitNotification())
      // it waits before sending the nodes 
      // from the Observable.of(...) statement
      .delay(NOTIFICATION_TIMEOUT)
  });
  // we return the resulting stream
  return outgoing;
}

එය උපකාරී වේ යැයි මම බලාපොරොත්තු වෙමි!


නිශ්චිත api ක්‍රම මෙහි කරන්නේ කුමක්ද යන්න ඔබට පැහැදිලි කළ හැකිද switchMap?
දිමිත්‍රි සයිට්සෙව්

1
අපි වින්ඩෝස් හි අපගේ ප්‍රතික්‍රියා ස්වදේශීය යෙදුමේ නැවත භාවිතා කළ හැකි දෑ භාවිතා කරමු. එය සංකීර්ණ, ඉහළ අසමමුහුර්ත ගැටලුවකට අලංකාර ක්‍රියාත්මක කිරීමේ විසඳුමක් වන අතර ඔවුන්ගේ ගිටර් නාලිකාව සහ GitHub ගැටළු හරහා විශිෂ්ට සහයෝගයක් ඇත. සංකීර්ණතාවයේ අතිරේක තට්ටුව එය වටී, ඇත්ත වශයෙන්ම එය විසඳීමට අදහස් කරන නිශ්චිත ගැටලුවට ඔබ පැමිණියහොත් පමණි.
මැට් හාර්ගට්

9

එය එතරම් අපහසු විය යුත්තේ ඇයි? එය යූඅයි තර්කනය පමණි. දැනුම්දීම් දත්ත සැකසීමට කැපවූ ක්‍රියාවක් භාවිතා කරන්න:

dispatch({ notificationData: { message: 'message', expire: +new Date() + 5*1000 } })

සහ එය ප්‍රදර්ශනය කිරීම සඳහා කැපවූ අංගයක්:

const Notifications = ({ notificationData }) => {
    if(notificationData.expire > this.state.currentTime) {
      return <div>{notificationData.message}</div>
    } else return null;
}

මෙම අවස්ථාවේ දී ප්‍රශ්න විය යුත්තේ "ඔබ පැරණි තත්වය පිරිසිදු කරන්නේ කෙසේද?", "කාලය වෙනස් වී ඇති සංරචකයක් දැනුම් දෙන්නේ කෙසේද" යන්නයි.

ඔබට TIMEOUT ක්‍රියාමාර්ගයක් ක්‍රියාත්මක කළ හැකි අතර එය setTimeout හි සංරචකයකින් යවනු ලැබේ.

සමහර විට නව දැනුම්දීමක් පෙන්වන සෑම විටම එය පිරිසිදු කිරීම හොඳයි.

කොහොමත් setTimeoutකොහේ හරි තැනක් තියෙන්න ඕන නේද? සංරචකයක් තුළ එය නොකරන්නේ ඇයි

setTimeout(() => this.setState({ currentTime: +new Date()}), 
           this.props.notificationData.expire-(+new Date()) )

අභිප්‍රේරණය වන්නේ “දැනුම්දීම මැකී යාම” ක්‍රියාකාරීත්වය සැබවින්ම UI සැලකිලිමත් වීමයි. එබැවින් එය ඔබේ ව්‍යාපාර තර්කනය පරීක්ෂා කිරීම සරල කරයි.

එය ක්‍රියාත්මක කරන්නේ කෙසේදැයි පරීක්ෂා කිරීම අර්ථවත් බවක් නොපෙනේ. දැනුම්දීම කල් ඉකුත් වන්නේ කවදාද යන්න තහවුරු කර ගැනීම අර්ථවත් කරයි. මේ අනුව මුරණ්ඩු කිරීමට අඩු කේතය, වේගවත් පරීක්ෂණ, පිරිසිදු කේතය.


1
මෙය ඉහළම පිළිතුර විය යුතුය.
mmla

7

වරණීය ක්‍රියාමාර්ග කල් ඉකුත්වීම ඔබට අවශ්‍ය නම්, ඔබට එය උත්සාහ කළ හැකිය මිඩ්ල්වෙයාර් ප්‍රවේශය . පොරොන්දු පදනම් කරගත් ක්‍රියාවන් තෝරා බේරා හැසිරවීම සම්බන්ධයෙන් මම සමාන ගැටලුවකට මුහුණ දුන් අතර මෙම විසඳුම වඩාත් නම්‍යශීලී විය.

ඔබගේ ක්‍රියාකාරී නිර්මාතෘ මේ වගේ බව ඔබට කියමු:

//action creator
buildAction = (actionData) => ({
    ...actionData,
    timeout: 500
})

කල් ඉකුත්වීම ඉහත ක්‍රියාවෙහි බහු අගයන් රඳවා ගත හැකිය

  • ms හි අංකය - නිශ්චිත කල් ඉකුත් වීමේ කාලයක් සඳහා
  • සත්‍ය - නියත කල් ඉකුත් වීමේ කාලයක් සඳහා. (මිඩ්ල්වෙයාර් හි හසුරුවනු ලැබේ)
  • නිර්වචනය නොකළ - වහාම යැවීම සඳහා

ඔබගේ මිඩ්ල්වෙයාර් ක්‍රියාත්මක කිරීම මේ වගේ ය:

//timeoutMiddleware.js
const timeoutMiddleware = store => next => action => {

  //If your action doesn't have any timeout attribute, fallback to the default handler
  if(!action.timeout) {
    return next (action)
  }

  const defaultTimeoutDuration = 1000;
  const timeoutDuration = Number.isInteger(action.timeout) ? action.timeout || defaultTimeoutDuration;

//timeout here is called based on the duration defined in the action.
  setTimeout(() => {
    next (action)
  }, timeoutDuration)
}

ඔබට දැන් ඔබගේ සියලු ක්‍රියා මෙම මිඩ්ල්වෙයාර් ස්තරය හරහා රීඩක්ස් භාවිතා කළ හැකිය.

createStore(reducer, applyMiddleware(timeoutMiddleware))

ඔබට සමාන උදාහරණ කිහිපයක් මෙහි සොයාගත හැකිය


6

මෙය කිරීමට සුදුසු ක්රමයක් භාවිතා රංගනයක් Thunk , රංගනයක් සඳහා ජනප්රිය මිඩ්ල්වෙයාර් වන රංගනයක් Thunk ප්රලේඛනය අනුව:

"ක්‍රියාවක් වෙනුවට ශ්‍රිතයක් නැවත ලබා දෙන ක්‍රියාකාරී නිර්මාණකරුවන් ලිවීමට රෙඩක්ස් තන්ක් මිඩ්ල්වෙයාර් ඔබට ඉඩ සලසයි. යම් ක්‍රියාවක් යැවීම ප්‍රමාද කිරීමට හෝ යම් කොන්දේසියක් සපුරා ඇත්නම් පමණක් පිටත් කර යැවීමට මාපටැඟිල්ල භාවිතා කළ හැකිය. අභ්‍යන්තර ශ්‍රිතයට ගබඩා ක්‍රම ලැබේ පිටත් කර getState පරාමිතීන් ලෙස ".

එබැවින් මූලික වශයෙන් එය ශ්‍රිතයක් නැවත ලබා දෙන අතර, ඔබේ යැවීම ප්‍රමාද කිරීමට හෝ එය තත්ව තත්වයට පත් කළ හැකිය.

ඉතින් මේ වගේ දෙයක් ඔබ වෙනුවෙන් කාර්යය කරන්න යනවා:

import ReduxThunk from 'redux-thunk';

const INCREMENT_COUNTER = 'INCREMENT_COUNTER';

function increment() {
  return {
    type: INCREMENT_COUNTER
  };
}

function incrementAsync() {
  return dispatch => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      dispatch(increment());
    }, 5000);
  };
}


4

Redux යනු ලස්සන වාචික පුස්තකාලයක් වන අතර එවැනි දේ සඳහා ඔබට Redux-thunk වැනි දෙයක් භාවිතා කිරීමට සිදුවනු ඇත.dispatch ශ්‍රිතයක් , එබැවින් ඔබට තත්පර කිහිපයකට පසුව දැනුම්දීම අවසන් කිරීමට යැවිය හැකිය.

වාචිකතාව සහ සංයුක්තතාව වැනි ගැටළු විසඳීම සඳහා මම පුස්තකාලයක් නිර්මාණය කර ඇති අතර ඔබේ උදාහරණය පහත පරිදි වේ:

import { createTile, createSyncTile } from 'redux-tiles';
import { sleep } from 'delounce';

const notifications = createSyncTile({
  type: ['ui', 'notifications'],
  fn: ({ params }) => params.data,
  // to have only one tile for all notifications
  nesting: ({ type }) => [type],
});

const notificationsManager = createTile({
  type: ['ui', 'notificationManager'],
  fn: ({ params, dispatch, actions }) => {
    dispatch(actions.ui.notifications({ type: params.type, data: params.data }));
    await sleep(params.timeout || 5000);
    dispatch(actions.ui.notifications({ type: params.type, data: null }));
    return { closed: true };
  },
  nesting: ({ type }) => [type],
});

ඒ නිසා අපි සමමුහුර්ත ක්‍රියාවන් තුළ දැනුම්දීම් පෙන්වීම සඳහා සමමුහුර්ත ක්‍රියා රචනා කරන්නෙමු, එමඟින් පසුබිම පිළිබඳ යම් තොරතුරක් ඉල්ලා සිටිය හැකිය, නැතහොත් දැනුම්දීම අතින් වසා තිබේද යන්න පසුව පරීක්ෂා කරන්න.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.