2.8.3 β€’ Published 4 months ago

quickrenard v2.8.3

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

QuickRenard Logo

🦊quickrenard🦊

🦊Quick Renardλ₯Ό μ œμž‘ν–ˆμŠ΅λ‹ˆλ‹€.🦊

1. μ •μ˜ 및 섀계

  1. 쿼리 기반의 μƒνƒœ μ •μ˜: 각 μƒνƒœλ₯Ό GraphQL μŠ€ν‚€λ§ˆμ²˜λŸΌ μ •μ˜ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μƒνƒœμ˜ νƒ€μž…, 초기 κ°’, μ˜μ‘΄μ„± 등을 λͺ…μ‹œμ μœΌλ‘œ ν‘œν˜„ν•©λ‹ˆλ‹€.
  2. 쿼리 및 변이 μž‘μ„±: μ‚¬μš©μžκ°€ μƒνƒœλ₯Ό μ‘°νšŒν•˜κ±°λ‚˜ μˆ˜μ •ν•  수 μžˆλ„λ‘ 쿼리와 변이λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

2. 라이브러리 κ΅¬ν˜„

  1. μƒνƒœ μ €μž₯μ†Œ: λͺ¨λ“  μƒνƒœλ₯Ό μ €μž₯ν•˜λŠ” 쀑앙 μ €μž₯μ†Œλ₯Ό λ§Œλ“­λ‹ˆλ‹€.
  2. 쿼리 해석기: 주어진 쿼리λ₯Ό ν•΄μ„ν•˜κ³  ν•΄λ‹Ήν•˜λŠ” μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” λ‘œμ§μ„ κ΅¬ν˜„ν•©λ‹ˆλ‹€.
  3. 변이(Mutation) 처리기: 주어진 변이(Mutation)λ₯Ό ν•΄μ„ν•˜κ³  μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” λ‘œμ§μ„ κ΅¬ν˜„ν•©λ‹ˆλ‹€.
  4. ꡬ독(subscription) λ©”μ»€λ‹ˆμ¦˜: νŠΉμ • μƒνƒœμ˜ 변이λ₯Ό ꡬ독(subscription)ν•˜κ³ , 변이가 κ°μ§€λ˜λ©΄ μ½œλ°±μ„ μ‹€ν–‰ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μ„ κ΅¬ν˜„ν•©λ‹ˆλ‹€.

3. React Hooks

  1. useStateQuery: 주어진 쿼리에 ν•΄λ‹Ήν•˜λŠ” μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” Hook을 μ œκ³΅ν•©λ‹ˆλ‹€.
  2. useStateMutation: 주어진 변이λ₯Ό μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜μ™€ μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” Hook을 μ œκ³΅ν•©λ‹ˆλ‹€.
  3. useStateSubscription: 주어진 μƒνƒœμ˜ λ³€ν™”λ₯Ό κ΅¬λ…ν•˜κ³ , λ³€ν™”κ°€ κ°μ§€λ˜λ©΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ¦¬λ Œλ”λ§ν•˜λŠ” Hook을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • μ‚¬μš©μžλŠ” 쿼리와 변이λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒνƒœμ— μ‰½κ²Œ μ ‘κ·Όν•˜κ³  μˆ˜μ •ν•  수 있으며,
  • ν•„μš”ν•œ μƒνƒœμ˜ λ³€ν™”λ§Œμ„ κ΅¬λ…ν•˜μ—¬ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ¦¬λ Œλ”λ§ν•  수 있게 λ©λ‹ˆλ‹€.

1. μƒνƒœ μ €μž₯μ†Œ (stateStore):

  • Quick Renard λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œλŠ” μ „μ—­μ μœΌλ‘œ κ΄€λ¦¬λ˜λŠ” stateStoreλΌλŠ” 쀑앙 μ €μž₯μ†Œλ₯Ό 톡해 μƒνƒœλ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€. 이 μ €μž₯μ†Œμ—λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λͺ¨λ“  μƒνƒœκ°€ μ €μž₯되며, 쿼리 기반의 μ ‘κ·Ό 방식을 μ‚¬μš©ν•˜μ—¬ νŠΉμ • μƒνƒœλ₯Ό κ²€μƒ‰ν•˜κ±°λ‚˜ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2. μƒνƒœ μŠ€ν‚€λ§ˆ (StateSchema):

  • μƒνƒœμ˜ ꡬ쑰와 κΈ°λŒ€λ˜λŠ” νƒ€μž…, κΈ°λ³Έκ°’ 등을 μ •μ˜ν•˜κΈ° μœ„ν•΄ μŠ€ν‚€λ§ˆλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 μƒνƒœμ˜ 초기 섀정을 μ‰½κ²Œ ν•  수 있으며, μƒνƒœ λ³€κ²½ μ‹œ μœ νš¨μ„± κ²€μ‚¬μ˜ κΈ°μ€€μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.

3. μƒνƒœ 변이 (setStateMutation):

  • 이 ν•¨μˆ˜λ₯Ό 톡해 μƒνƒœλ₯Ό μˆ˜μ •ν•˜κ²Œ λ©λ‹ˆλ‹€. ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” μŠ€ν‚€λ§ˆλ₯Ό λ°”νƒ•μœΌλ‘œ μƒνƒœμ˜ μœ νš¨μ„± 검사λ₯Ό μˆ˜ν–‰ν•  수 있으며, ν•΄λ‹Ή μƒνƒœμ— λ³€ν™”κ°€ μžˆμ„ 경우, κ·Έ μƒνƒœλ₯Ό κ΅¬λ…ν•˜κ³  μžˆλŠ” λͺ¨λ“  κ΅¬λ…μžλ“€μ—κ²Œ μ•Œλ¦Όμ„ λ³΄λƒ…λ‹ˆλ‹€.

4. μƒνƒœ ꡬ독 (subscribeStateChange):

  • νŠΉμ • μƒνƒœμ˜ λ³€ν™”λ₯Ό κ΄€μ°°ν•˜κ³ μž ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλŠ” 이 ν•¨μˆ˜λ₯Ό 톡해 ν•΄λ‹Ή μƒνƒœμ˜ λ³€ν™”λ₯Ό κ΅¬λ…ν•©λ‹ˆλ‹€. μƒνƒœκ°€ 변경될 λ•Œλ§ˆλ‹€ κ΅¬λ…ν•˜κ³  μžˆλŠ” μ»΄ν¬λ„ŒνŠΈλŠ” 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜κ²Œ λ©λ‹ˆλ‹€. 이λ₯Ό 톡해 μƒνƒœ 변화에 λ”°λ₯Έ λ¦¬λ Œλ”λ§μ΄λ‚˜ λ‹€λ₯Έ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

🦊Ver 1.2.0🦊

νƒ€μž… 검증 둜직 μΆ”κ°€

1. Enum 검증:

  • enum ν‚€λ₯Ό 톡해 ν—ˆμš©λœ λ¬Έμžμ—΄ 집합을 μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν•΄λ‹Ή 값이 enum에 μ •μ˜λœ λ¬Έμžμ—΄ 쀑 ν•˜λ‚˜μΈμ§€ κ²€μ‚¬ν•©λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, μƒνƒœκ°€ νŠΉμ • λ¬Έμžμ—΄ κ°’λ“€ 쀑 ν•˜λ‚˜λ§Œ κ°€μ Έμ•Ό ν•  경우 μ‚¬μš©λ©λ‹ˆλ‹€.

2. 객체 속성 검증:

  • properties ν‚€λ₯Ό 톡해 객체의 각 속성에 λŒ€ν•œ μŠ€ν‚€λ§ˆλ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 각 μ†μ„±μ˜ μœ ν˜•μ„ κ²€μ‚¬ν•˜μ—¬ ν•΄λ‹Ή 속성이 μ˜¬λ°”λ₯Έ μœ ν˜•μΈμ§€ ν™•μΈν•©λ‹ˆλ‹€.
  • 객체 λ‚΄λΆ€μ˜ 각 속성이 μ •μ˜λœ μŠ€ν‚€λ§ˆλ₯Ό λ”°λ₯΄λŠ”지 κ²€μ‚¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ©λ‹ˆλ‹€.

3. λ°°μ—΄ ν•­λͺ© νƒ€μž… 검증:

  • λ°°μ—΄μ˜ λͺ¨λ“  ν•­λͺ©μ΄ ν•΄λ‹Ή μŠ€ν‚€λ§ˆλ₯Ό μ€€μˆ˜ν•˜λŠ”μ§€ κ²€μ‚¬ν•©λ‹ˆλ‹€.
  • λ°°μ—΄ λ‚΄λΆ€μ˜ 각 ν•­λͺ©μ΄ μ •μ˜λœ μŠ€ν‚€λ§ˆλ₯Ό λ”°λ₯΄λŠ”지 κ²€μ‚¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ©λ‹ˆλ‹€.

🦊Ver 2.0.0🦊

ν•¨μˆ˜ μ „μ—­ κ΄€λ¦¬μ†Œ functionStore μΆ”κ°€

1. 관리할 수 μžˆλŠ” λŒ€ν‘œμ μΈ ν•¨μˆ˜ μœ ν˜•:

  • 순수 ν•¨μˆ˜: λ™μΌν•œ μΈμžμ— λŒ€ν•΄ 항상 λ™μΌν•œ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜κ³ , μ™ΈλΆ€ μƒνƒœλ₯Ό λ³€κ²½ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

  • μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜: λ¬Έμžμ—΄ 처리, λ‚ μ§œ 계산, 숫자 ν¬λ§·νŒ… λ“± μž¬μ‚¬μš© κ°€λŠ₯ν•œ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.

  • 헬퍼 ν•¨μˆ˜: 반볡적으둜 μ‚¬μš©λ˜λŠ” λ‘œμ§μ„ μΆ”μƒν™”ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€ (예: API μš”μ²­).

2. μœ„μ™€ 같은 ν•¨μˆ˜λ“€μ„ 관리할 수 μžˆμœΌλ‚˜, μ£Όμ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€:

  • μ‚¬μ΄λ“œ μ΄νŽ™νŠΈ: ν•¨μˆ˜κ°€ μ™ΈλΆ€ μ‹œμŠ€ν…œμ˜ μƒνƒœμ— 영ν–₯을 μ£Όκ±°λ‚˜ κ·Έλ‘œλΆ€ν„° 영ν–₯을 λ°›λŠ” 경우, (μ˜ˆμ‹œ: λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Όν•˜κ±°λ‚˜ μ™ΈλΆ€ APIλ₯Ό ν˜ΈμΆœν•˜λŠ” ν•¨μˆ˜) μ˜ˆμΈ‘ν•˜μ§€ λͺ»ν•œ κ²°κ³Όλ₯Ό μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μƒνƒœ μ˜μ‘΄μ„±: ν•¨μˆ˜κ°€ λ‚΄λΆ€ μƒνƒœμ— μ˜μ‘΄ν•˜λŠ” 경우, κ·Έ μƒνƒœμ˜ λ³€ν™”κ°€ ν•¨μˆ˜μ˜ 결과에 영ν–₯을 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.

  • μŠ€μ½”ν”„μ™€ ν΄λ‘œμ €: ν•¨μˆ˜κ°€ νŠΉμ • μŠ€μ½”ν”„μ˜ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 경우, μ΄λŸ¬ν•œ μ˜μ‘΄μ„±μ„ 관리해야 ν•©λ‹ˆλ‹€.

  • λ™μ‹œμ„± μ œμ–΄: μ—¬λŸ¬ κ΅¬λ…μžκ°€ λ™μΌν•œ ν•¨μˆ˜μ˜ κ²°κ³Όλ₯Ό ꡬ독할 λ•Œ λ°œμƒν•˜λŠ” λ™μ‹œμ„± 이슈λ₯Ό 관리해야 ν•©λ‹ˆλ‹€.

  • p.s: QuickRenard 2.1.0 λ²„μ „μ—μ„œλŠ” ν•¨μˆ˜ ν˜ΈμΆœμ— λŒ€μ‘ν•˜λŠ” ꡬ독과 ꡬ독 μ·¨μ†Œ 과정이 라이브러리 λ‚΄λΆ€μ μœΌλ‘œ μžλ™μœΌλ‘œ κ΄€λ¦¬λ˜λ„λ‘ κ°œμ„ ν•˜μ˜€μŠ΅λ‹ˆλ‹€. κ°„λ‹¨νžˆ 말해, QuickRenardκ°€ ꡬ독과 ꡬ독 μ·¨μ†Œμ˜ μ„Έμ„Έν•œ 관리λ₯Ό μžλ™ν™”ν•¨μœΌλ‘œμ¨, κ°œλ°œμžλŠ” ν•¨μˆ˜ 등둝 및 ν˜ΈμΆœμ— 집쀑할 수 있으며, 더 μ•ˆμ •μ μ΄κ³  μœ μ§€λ³΄μˆ˜κ°€ μ‰¬μš΄ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμ„ κ²ƒμž…λ‹ˆλ‹€.

functionStoreλ₯Ό μ‚¬μš©ν•˜λ €λ©΄, μ•„λž˜μ˜ !!! How to use !!! λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

🦊Ver 2.3.0 - Ver 2.5.0🦊

μƒνƒœ 캐싱 둜직 μΆ”κ°€:

μ„±λŠ₯ μ΅œμ ν™”λ₯Ό μœ„ν•œ μƒˆλ‘œμš΄ κΈ°λŠ₯:

  1. μƒνƒœ 캐싱을 톡해, 자주 μ ‘κ·Όν•˜λŠ” μƒνƒœμ— λŒ€ν•œ μ‹ μ†ν•œ 검색이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 라이브러리 μ‚¬μš© μ‹œ, μ„±λŠ₯이 μ „λ°˜μ μœΌλ‘œ κ°œμ„ λ  κ²ƒμž…λ‹ˆλ‹€.

  2. 이전에 μš”μ²­λœ μƒνƒœ 값을 μΊμ‹œμ— μ €μž₯ν•©λ‹ˆλ‹€. 같은 μƒνƒœλ₯Ό λ‹€μ‹œ μš”μ²­ν•  λ•Œ μ‹ μ†ν•œ 응닡을 받을 수 μžˆμŠ΅λ‹ˆλ‹€. λ³΅μž‘ν•œ 계산 ν˜Ήμ€ λ°μ΄ν„°λ² μ΄μŠ€ 쿼리가 ν•„μš”ν•œ μƒνƒœμ˜ 경우, 특히 이 κΈ°λŠ₯은 μœ μš©ν•  κ²ƒμž…λ‹ˆλ‹€.

  3. λ„€νŠΈμ›Œν¬ 지연, μ„œλ²„ κ³ΌλΆ€ν•˜λ₯Ό μ˜ˆλ°©ν•˜λŠ” 데에 νš¨κ³Όμ μž…λ‹ˆλ‹€. 원격 데이터λ₯Ό μƒνƒœλ‘œ κ΄€λ¦¬ν•˜λŠ” 경우, 캐싱은 λ„€νŠΈμ›Œν¬ μš”μ²­ 수λ₯Ό μ€„μž„μœΌλ‘œμ¨, 데이터 전솑을 효율적으둜 μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

캐싱 κ΄€λ ¨ μ£Όμ˜μ‚¬ν•­:

  1. μΊμ‹œλŠ” λ©”λͺ¨λ¦¬ 관리λ₯Ό μœ„ν•΄, λ””ν΄νŠΈ κ°’μœΌλ‘œ 15λΆ„ 뒀에 λ§Œλ£Œλ©λ‹ˆλ‹€.

  2. Ver 2.5.0λΆ€ν„° μΊμ‹œ 만료 μ‹œκ°„μ„ μž„μ˜λ‘œ μ‘°μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 방법 및 μ£Όμ˜μ‚¬ν•­μ€ ❗❗❗ How to use ❗❗❗λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

μ—…λ°μ΄νŠΈλ₯Ό 톡해 QuickRenardλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ„±λŠ₯을 κ°œμ„ ν•˜κ³ , 보닀 효율적으둜 μƒνƒœ 관리λ₯Ό ν•  수 μžˆλ„λ‘ μ§€μ›ν•©λ‹ˆλ‹€. Ver 2.3.0 μ—…λ°μ΄νŠΈλŠ” 특히 λŒ€κ·œλͺ¨ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 및 데이터 집약적 μž‘μ—…μ— 쀑점을 두고 μ§„ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.

🦊Ver 2.6.0 - Ver 2.7.0🦊

  • μƒνƒœ 관리 μ‹œμŠ€ν…œμ΄ λ”μš± κ°•λ ₯ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€. 이제 μƒνƒœ κ°„μ˜ λ³΅μž‘ν•œ 쒅속성을 κ·Έλž˜ν”„ 탐색 μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ 효과적으둜 관리할 수 μžˆμŠ΅λ‹ˆλ‹€. DFS(깊이 μš°μ„  탐색)와 BFS(λ„ˆλΉ„ μš°μ„  탐색) μ•Œκ³ λ¦¬μ¦˜μ„ ν™œμš©ν•˜μ—¬, μƒνƒœμ˜ μ—…λ°μ΄νŠΈκ°€ λ‹€λ₯Έ μƒνƒœμ— λ―ΈμΉ˜λŠ” 영ν–₯을 효과적으둜 μ²˜λ¦¬ν•©λ‹ˆλ‹€.
  1. DFS(깊이 μš°μ„  탐색): 깊게 μ—°κ²°λœ μƒνƒœ κ°„μ˜ 쒅속성을 νƒμƒ‰ν•©λ‹ˆλ‹€. 이 방식은 μƒνƒœ 간에 κΉŠμ€ 연결이 μžˆλŠ” κ²½μš°μ— μ ν•©ν•©λ‹ˆλ‹€.
  2. BFS(λ„ˆλΉ„ μš°μ„  탐색): 넓은 λ²”μœ„μ˜ μƒνƒœ κ°„μ˜ 쒅속성을 νƒμƒ‰ν•©λ‹ˆλ‹€. 이 방식은 더 넓은 λ²”μœ„μ˜ μƒνƒœ κ°„ 영ν–₯을 관리할 λ•Œ μœ μš©ν•©λ‹ˆλ‹€.
  3. Ver 2.7.0λΆ€ν„°λŠ” μƒνƒœ κ°„μ˜ 쒅속성을 관리할 μ‹œ, updateStateν•¨μˆ˜κ°€ DFS둜 μ²˜λ¦¬ν• μ§€, BFS둜 μ²˜λ¦¬ν• μ§€ μžλ™μœΌλ‘œ νŒλ³„ν•΄ μ€λ‹ˆλ‹€. 이λ₯Ό 톡해 μƒνƒœ 관리가 λ”μš± μœ μ—°ν•˜κ³  효율적으둜 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

DFS λ˜λŠ” BFS κ΄€λ ¨ 섀정을 μ‚¬μš©ν•˜λ €λ©΄, μ•„λž˜μ˜ ❗❗❗ How to use ❗❗❗ λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

🦊Ver 2.7.1 - 🦊

  • Lodashλ‘œλΆ€ν„° λ…λ¦½ν–ˆμŠ΅λ‹ˆλ‹€.

🦊Ver 2.8.1 - 🦊

  • μƒνƒœ 관리 ν›…μ˜ κ°•ν™” 및 κΈ°λŠ₯ ν™•μž₯

μ£Όμš” λ³€κ²½ 사항:

  1. useStateQuery κ°œμ„ : Ver 2.8.0μ—μ„œ useStateQueryλŠ” μƒνƒœμ˜ λ‘œλ”© 및 μ—λŸ¬ 처리λ₯Ό 보닀 효과적으둜 κ΄€λ¦¬ν•©λ‹ˆλ‹€. λ°˜ν™˜ κ°μ²΄μ—λŠ” data ν•„λ“œ 외에도 loading 및 error ν•„λ“œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμ–΄, μƒνƒœ λ‘œλ”©μ˜ 진행 상황과 λ°œμƒν•  수 μžˆλŠ” μ—λŸ¬λ₯Ό μ‰½κ²Œ 좔적할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ μΆ”κ°€ ν•„λ“œλŠ” μƒνƒœ 쑰회 κ³Όμ •μ—μ„œμ˜ λ‹€μ–‘ν•œ 상황듀을 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œ μ„Έμ‹¬ν•˜κ²Œ μ²˜λ¦¬ν•  수 있게 ν•΄μ£Όμ–΄, 더 κ°•λ ₯ν•˜κ³  μœ μ—°ν•œ μƒνƒœ 관리가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

  2. useStateMutation ν™•μž₯: μƒνƒœ λ³€κ²½ 둜직이 λΉ„λ™κΈ°μ μœΌλ‘œ 처리될 수 μžˆλ„λ‘ useStateMutation이 κ°œμ„ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μƒνƒœ λ³€κ²½ μ‹œ λ‘œλ”© μƒνƒœμ™€ 였λ₯˜ 처리λ₯Ό 관리할 수 μžˆλŠ” κΈ°λŠ₯이 μΆ”κ°€λ˜μ—ˆμœΌλ©°, μ΄λŠ” API 호좜과 같은 비동기 μž‘μ—…μ— 맀우 μœ μš©ν•©λ‹ˆλ‹€. μ‚¬μš©μžλŠ” μƒνƒœ λ³€κ²½ ν•¨μˆ˜(mutate), ν˜„μž¬ μƒνƒœ(state), λ‘œλ”© μƒνƒœ(loading), 그리고 λ°œμƒν•œ 였λ₯˜(error)λ₯Ό μ‰½κ²Œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

  3. useStateSubscription의 μƒνƒœ λ³€ν™” 감지 κ°œμ„ : μƒνƒœ λ³€ν™”λ₯Ό 더 μ •κ΅ν•˜κ²Œ 감지할 수 μžˆλ„λ‘ useStateSubscription을 κ°œμ„ ν–ˆμŠ΅λ‹ˆλ‹€. 이제 콜백 ν•¨μˆ˜κ°€ μ΅œμ‹  μƒνƒœλ‘œ μœ μ§€λ˜λ©΄μ„œ, μƒνƒœ λ³€ν™”λ₯Ό 보닀 μ •ν™•ν•˜κ²Œ κ°μ§€ν•˜κ³  λ°˜μ‘ν•©λ‹ˆλ‹€.

  4. νƒ€μž…μŠ€ν¬λ¦½νŠΈ 지원 κ°•ν™”: hooks.d.ts νŒŒμΌμ„ 톡해 λͺ¨λ“  ν›…μ˜ νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ •μ˜λ₯Ό λ³΄μ™„ν–ˆμŠ΅λ‹ˆλ‹€. useStateQuery와 useStateMutation은 각각 StateQueryResult 및 StateMutationResult μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°˜ν™˜ νƒ€μž…μ„ λͺ…ν™•νžˆ μ •μ˜ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ νƒ€μž… μ •μ˜λŠ” κ°œλ°œμžλ“€μ΄ 훅을 더 μ •ν™•ν•˜κ³  μ•ˆμ „ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ„λ‘ λ•μŠ΅λ‹ˆλ‹€.

  5. updateState ν•¨μˆ˜μ˜ 비동기 처리 κ°•ν™”: updateState ν•¨μˆ˜λŠ” 이제 μƒνƒœλ₯Ό λΉ„λ™κΈ°μ μœΌλ‘œ μ—…λ°μ΄νŠΈν•  수 μžˆλŠ” κΈ°λŠ₯을 κ°–μΆ”μ—ˆμŠ΅λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” μƒνƒœ λ³€κ²½κ³Ό ν•¨κ»˜, ν•΄λ‹Ή μƒνƒœμ— μ’…μ†λœ λͺ¨λ“  μƒνƒœλ“€λ„ μ μ ˆν•œ 탐색 μ „λž΅ (DFS λ˜λŠ” BFS)을 μ‚¬μš©ν•˜μ—¬ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€. 이 λ³€ν™”λŠ” λ‹€μŒκ³Ό 같은 이점을 μ œκ³΅ν•©λ‹ˆλ‹€:

5-1. 비동기 μƒνƒœ 관리: updateState ν•¨μˆ˜λŠ” Promiseλ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ, μƒνƒœ μ—…λ°μ΄νŠΈ μž‘μ—…μ˜ μ™„λ£Œλ₯Ό λΉ„λ™κΈ°μ μœΌλ‘œ 기닀릴 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” API 호좜과 같은 μ™ΈλΆ€ 비동기 μž‘μ—…μ„ ν†΅ν•©ν•˜λŠ” 데 특히 μœ μš©ν•©λ‹ˆλ‹€.

5-2. 쒅속 μƒνƒœ μ—…λ°μ΄νŠΈ: μƒνƒœ κ°„μ˜ 쒅속성을 κ³ λ €ν•˜μ—¬, ν•œ μƒνƒœμ˜ μ—…λ°μ΄νŠΈκ°€ μ’…μ†λœ λ‹€λ₯Έ μƒνƒœλ“€μ—λ„ μžλ™μœΌλ‘œ λ°˜μ˜λ©λ‹ˆλ‹€. 이λ₯Ό 톡해 λ³΅μž‘ν•œ μƒνƒœ κ°„μ˜ 관계λ₯Ό μ‰½κ²Œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

5-3. DFS 및 BFS μ „λž΅: μƒνƒœ μ—…λ°μ΄νŠΈ μ „λž΅μ€ μƒνƒœ κ°„μ˜ 관계에 따라 DFS(깊이 μš°μ„  탐색) λ˜λŠ” BFS(λ„ˆλΉ„ μš°μ„  탐색)둜 κ²°μ •λ©λ‹ˆλ‹€. μ΄λŠ” μƒνƒœ ꡬ쑰에 따라 졜적의 μ—…λ°μ΄νŠΈ μ „λž΅μ„ μ„ νƒν•˜μ—¬ 효율적으둜 μƒνƒœλ₯Ό 관리할 수 있게 ν•©λ‹ˆλ‹€.

이번 μ—…λ°μ΄νŠΈλŠ” μƒνƒœ 관리에 μžˆμ–΄ 비동기 μž‘μ—…μ˜ 톡합, λ³΅μž‘ν•œ μƒνƒœ κ΄€κ³„μ˜ 관리, 그리고 μƒνƒœ μ—…λ°μ΄νŠΈ μ „λž΅μ˜ μ΅œμ ν™”λ₯Ό μ§€μ›ν•¨μœΌλ‘œμ¨, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μƒνƒœ 관리λ₯Ό λ”μš± κ°•λ ₯ν•˜κ³  μœ μ—°ν•˜κ²Œ λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€. μ΄λŸ¬ν•œ κ°œμ„ μ€ 특히 μ™ΈλΆ€ 데이터 μ†ŒμŠ€μ™€μ˜ μƒν˜Έμž‘μš© 및 λ³΅μž‘ν•œ μƒνƒœ 쒅속성을 λ‹€λ£° λ•Œ κ·Έ 효과λ₯Ό λ°œνœ˜ν•  κ²ƒμž…λ‹ˆλ‹€.

❗❗❗ How to use ❗❗❗

🦊 quickrenard 🦊

: A Simple State Management in React

QuickRenard(quickrenard) is a lightweight state management solution for React applications. By providing clear paths for data querying, mutation, and subscriptions, QuickRenard streamlines the state-sharing process between components, even if they aren't directly related in the component tree.

Setup and Initialization

To start using quickrenard, you first need to define a schema for your state and then initialize the store.

1. Define State Schema:

Your state is structured based on a schema. This schema outlines the shape, type, and default values of your state properties.

// stateSchema.js
export const stateSchema = {
    'childData.data': {
        type: 'string',
        defaultValue: 'initialValue'
    }
};

2. Initialize Store:

Once you have your schema in place, initialize the state store with it. This sets up the initial state for your application.

// stateStore.js
import { initializeStore } from 'quickrenard';
import { stateSchema } from './stateSchema';

initializeStore(stateSchema);

3. Using quickrenard in Components

Querying State:

To access a state property within a component, use the useStateQuery hook. This hook queries and retrieves the value of the specified state property.

const data = useStateQuery("childData.data");

Mutating State:

For updating the state, use the useStateMutation hook. This hook provides a function to update a specific state property and also returns the current value of that property.

const [updateChildData, data] = useStateMutation("childData.data");

Subscribing to State Changes:

If you want a component to react to changes in the state, use the useStateSubscription hook. It allows you to provide a callback function that will be called whenever the specified state property changes.

useStateSubscription("childData.data", handleDataChange);

Example: Sharing State Between Distant Components

Consider a scenario where you have two components, Child and Cousin, that aren't directly related in the component tree. Yet, you want to share state data between them using QuickRenard.

Child Component:

This component mutates the data.

// Child.js
import React from 'react';
import { useStateMutation } from 'quickrenard';

function Child() {
  const [updateChildData, data] = useStateMutation("childData.data");

  const handleUpdateData = () => {
    updateChildData("Updated Data from Child");
    console.log("Data updated!");
  };

  return (
    <div>
      <h3>Child Component</h3>
      <p>Data: {data}</p>
      <button onClick={handleUpdateData}>Update Data</button>
    </div>
  );
}

Cousin Component:

This component queries the data and subscribes to its changes.

// Cousin.js
import React from 'react';
import { useStateQuery, useStateSubscription } from 'quickrenard';

function Cousin() {
  const data = useStateQuery("childData.data");

  const handleDataChange = () => {
    console.log("Child data has changed!");
  };

  useStateSubscription("childData.data", handleDataChange);

  return (
    <div>
      <h3>Cousin Component</h3>
      <p>Data from Child: {data}</p>
    </div>
  );
}

With quickrenard, even if Child and Cousin aren't directly related, the state update in Child will trigger a subscription callback in Cousin, allowing seamless state sharing across different parts of your React application.

🦊Ver 1.2.0🦊

Added type validation logic.

  1. Enum validation:
  • You can define an allowed set of string values through the enum key.
  • It checks if the value is one of the strings defined in the enum.
  • This is used when the state should only have one of specific string values.
  1. Object property validation:
  • You can define a schema for each property of the object using the properties key.
  • It verifies the type of each property to ensure it's of the correct type.
  • It's used to check if each property within the object adheres to the defined schema.
  1. Array item type validation:
  • It checks if all items in the array adhere to the specified schema.
  • This is used to verify if each item inside the array follows the defined schema.

🦊Version 2.0.0🦊

Global function management feature 'functionStore' added

1. List of representative function types that can be managed:

  • Pure Functions: Functions that always return the same result for the same arguments without changing external state.

  • Utility Functions: Functions that provide reusable functionalities such as string processing, date calculations, number formatting, etc.

  • Helper Functions: Functions that abstract commonly used logic throughout the application (e.g., API requests).

2. While this function store can effectively manage the above types of functions, the following precautions are necessary:

  • Side Effects: Functions that affect or are affected by the state of external systems, (such as accessing a database or calling external APIs) can lead to unpredictable results.

  • State Dependency: Functions that depend on internal state may have results that are affected by changes to that state.

  • Scope and Closures: Functions that use variables from a specific scope need to have these dependencies managed.

  • Concurrency Control: Issues of concurrency that arise when multiple subscribers subscribe to the results of the same function must be managed.

🦊 Ver 2.1.0: State & Function Management in React 🦊

QuickRenard is your go-to library for streamlined global state and function management within React applications. The latest update, version 2.0.0, introduces a game-changing feature: the functionStore. This new capability complements the existing state management tools, enabling developers to create, invoke, and listen to global functions throughout their component hierarchy. It simplifies the management of cross-component logic and reduces the complexity of prop drilling.

🦊 What's New in Version 2.1.0 🦊

  • FunctionStore: A global registry for functions to be accessed and executed across components.
  • Function Invocation: Call any registered global function from anywhere within your app.
  • Function Subscriptions: Set up listeners for function calls to manage side effects or perform cleanup tasks.
  • Enhanced Code Maintainability: Abstract common logic into globally accessible functions, leading to cleaner and more maintainable codebases.

🦊 Quick Start with QuickRenard's Function Store 🦊

  • Step 1: Import function management APIs from QuickRenard.
import { registerFunction, callFunction } from 'quickrenard';
  • Step 2: Register functions that can be globally accessed.
registerFunction('logActivity', message => console.log(`Activity: ${message}`));
  • Step 3: Invoke registered functions from any component, passing required arguments.
callFunction('logActivity', 'User logged in');
  • Step 4: Set up subscriptions if you want components to react to function invocations.
// This part of the API is now internally managed by QuickRenard, no need for manual subscription.
  • Step 5: Unsubscribe from functions to clean up listeners.
// This is also managed internally when components unmount or when you stop using the function in QuickRenard.
  • QuickRenard version 2.0.0 makes your components more independent and your application more scalable by providing a central hub for state and function management.

🦊Practical Examples with QuickRenard🦊

Example: Inter-Component Communication with State and Functions

  • Let's look at how components like Child and Cousin can interact through shared state and functions without direct lineage or prop drilling.

1. Child Component:

  • Here, Child updates shared state and provides a function for others to call.
// Child.js
import React from 'react';
import { useStateMutation, registerFunction } from 'quickrenard';

function Child() {
  const [setChildData, childData] = useStateMutation("childData.data");

  const handleUpdateData = () => {
    setChildData("Updated Data from Child");
    console.log("Child data updated.");
  };  

  // Register a function for others to invoke
  registerFunction('childFunction', message => {
    console.log("Child received a message:", message);
    return "Message processed by Child";
  });

  return (
    <div>
      <h3>Child Component</h3>
      <p>Data: {childData}</p>
      <button onClick={handleUpdateData}>Update Data</button>
    </div>
  );
}

export default Child;

2. Cousin Component:

  • Cousin listens for state changes and can invoke Child's function.
// Cousin.js
import React, { useEffect } from 'react';
import { useStateQuery, useStateSubscription, callFunction } from 'quickrenard';

function Cousin() {
  const childData = useStateQuery("childData.data");

  useStateSubscription('childData.data', () => {
    console.log("Child data has changed!");
    // Invoke the function registered by Child
    try {
      const response = callFunction('childFunction', 'Hello World! - from Cousin');
      console.log('Response from Child:', response);
    } catch (error) {
      console.error(error.message);
    }
  });

  useEffect(() => {
    // This will run once when the component mounts
    console.log('Cousin mounted. Initial data:', childData);
  }, []); // Empty dependency array to mimic componentDidMount behavior

  return (
    <div>
      <h3>Cousin Component</h3>
      <p>Data from Child: {childData}</p>
    </div>
  );
}

export default Cousin;

🦊Ver 2.3.0 - Ver 2.5.0🦊

Added State Caching Logic:

  1. New Features for Performance Optimization: State caching enables swift retrieval of frequently accessed states, leading to overall performance improvements when using the library.

  2. Previously requested state values are stored in the cache. This allows for quick responses when the same state is requested again. This feature is especially beneficial for states that require complex calculations or database queries.

  3. It is effective in preventing network delays and server overloads. When managing remote data as state, caching can reduce the number of network requests, making data transfer more efficient.

Cautions Related to Caching:

  1. To manage memory, the cache expires after 15 minutes(default).

  2. From Ver 2.5.0 onwards, you can adjust the cache expiration time at your discretion. For the method and precautions, please refer to the following.

  3. Caution: The getCacheObject function exposes the library's internal state to the outside. This function should be used for development and debugging purposes only. Modifying the cache object externally can lead to unexpected issues in the library. Instead of directly altering the cache object, please use the APIs provided by the library to change the state. While it is possible to read and monitor the contents of the cache object, altering it is not recommended.

// Example of using quickrenard
import { initializeStore, getCacheObject, subscribeStateChange } from 'quickrenard';
import { stateSchema } from './stateSchema';

// Example: Set cache expiration time to 30 minutes
initializeStore(stateSchema, { cacheExpirationTime: 1800000 });

/** 🦊Optional Usage Example🦊: Function for cache expiration countdown */

// Function for cache expiration countdown
function cacheExpirationCountdown() {
  // Get the current time
  const now = performance.now();

  // Access the cache object
  const cache = getCacheObject();

  console.clear();
  console.log("Cache Expiration Countdown:");

  // Iterate through each cache key and display the remaining time
  Object.keys(cache).forEach(key => {
    const record = cache[key];
    if (record) {
      const remainingTime = record.expirationTime - now;
      if (remainingTime > 0) {
        console.log(`${key}: ${Math.ceil(remainingTime / 1000)} seconds remaining`);
      } else {
        console.log(`${key}: Expired`);
      }
    }
  });
}

// 🦊Optionally, run the countdown periodically🦊
setInterval(cacheExpirationCountdown, 1000);

/**  🦊Note🦊: This is an optional feature for monitoring cache expiration in the console.
     Use it primarily for development and debugging purposes. It should be used
     cautiously in a production environment as it can impact performance. */

// Example of subscribing to state changes
subscribeStateChange("someStateKey", (newState) => {
  console.log("State changed:", newState);
});

Through this update, QuickRenard aims to enhance application performance and enable more efficient state management. The Ver 2.3.0 update has been focused particularly on large-scale applications and data-intensive tasks.

🦊Ver 2.6.0 - Ver 2.7.0🦊

  • The state management system has become more powerful. You can now effectively manage complex dependencies between states using graph traversal algorithms. Utilize Depth-First Search (DFS) and Breadth-First Search (BFS) algorithms to effectively handle the impacts of state updates on other states.
  1. Depth-First Search (DFS): Explores dependencies deeply connected between states. This method is suitable when there are deep connections between states.
  2. Breadth-First Search (BFS): Explores dependencies across a wider range of states. This method is useful for managing influences across a broader spectrum of states.
  3. Enhanced State Management(❗Ver 2.7.0❗): The state management system is now even more intelligent. It automatically determines the most effective graph traversal strategy (DFS or BFS) to manage complex dependencies between states. This enhancement simplifies the process of managing state updates and their impacts on other states.

- Key Features:

  1. Automated Strategy Selection: The system now automatically selects between Depth-First Search (DFS) and Breadth-First Search (BFS) based on the nature of state dependencies.
  • DFS is chosen for deeply connected state dependencies (e.g., A -> B -> C).
  • BFS is used when a state has multiple parallel dependencies (e.g., A -> B, C, D).
  1. Simplified State Updates: Users no longer need to manually choose between DFS and BFS. The system intelligently decides the optimal approach, making state management more efficient and effective.

🦊 Using setStateDependencies and updateState Functions 🦊

  1. setStateDependencies(dependencies): Define the dependencies between different states. The system will use these dependencies to determine the traversal strategy.
const dependencies = {
    'childData.data': ['parentData', 'siblingData'],
};
setStateDependencies(dependencies);
  1. updateState(stateKey, newValue): Update a state, and the system will automatically use DFS or BFS as needed.
const newData = "Some Data";
updateState('childData.data', newData);
console.log("State updated with the appropriate strategy");
  • This approach provides a more streamlined and powerful tool for managing complex state dependencies, allowing for more tailored and efficient state updates.

🦊 Example Usage: 🦊

  1. child.js
import React from 'react';
import { useStateMutation, updateState } from 'quickrenard';

function Child() {
    const [setData, data] = useStateMutation('childData.data');

    const handleUpdateData = () => {
        const newData = "Updated Data from Child";
        updateState('childData.data', newData);
        console.log("State updated with the appropriate strategy");

        // Update the state using the useStateMutation hook
        setData(newData);
    };

    return (
        <div>
            <h3>Child Component</h3>
            <p>Data: {data}</p>
            <button onClick={handleUpdateData}>Update Data</button>
        </div>
    );
}

export default Child;
  1. stateSchema.js
export const stateSchema = {
    'childData.data': {
        type: 'string',
        defaultValue: 'Initial Child Data',
        // Define dependencies that will trigger BFS
        dependencies: ['parentData', 'siblingData'] // These are parallel dependencies
    },
    'parentData': {
        type: 'string',
        defaultValue: 'Initial Parent Data'
    },
    'siblingData': {
        type: 'string',
        defaultValue: 'Initial Sibling Data'
    }
};
  1. stateStore.js
import { initializeStore, setStateDependencies } from 'quickrenard';
import { stateSchema } from './stateSchema';

// Define state dependencies
const dependencies = {
    'childData.data': ['parentData', 'siblingData'],
};

// Initialize Store
initializeStore(stateSchema);

// Set state dependencies
setStateDependencies(dependencies);

🦊 Summary 🦊

  • Ver 2.7.0 simplifies state management in applications with complex dependencies, automatically choosing the most efficient graph traversal strategy (DFS or BFS) based on the defined state dependencies. This enhancement streamlines state updates, reducing the need for manual intervention and improving efficiency.

🦊Ver 2.7.1 - 🦊

  • Independent from Lodash.

🦊Ver 2.8.1 ~ 🦊

Enhancement and Expansion of State Management Hooks

Key Changes:

  1. Improvement in useStateQuery: In Ver 2.8.0, useStateQuery has been enhanced to manage the loading and error states of data more effectively. In addition to the data field, the returned object now includes loading and error fields. These additions enable easy tracking of the data loading process and any potential errors that might occur. The inclusion of these fields allows for more detailed and nuanced handling of various scenarios that may arise during the state querying process, facilitating stronger and more flexible state management.

  2. Expansion of useStateMutation: The logic for state change in useStateMutation has been enhanced to handle asynchronous operations. Added features manage the loading state and error handling during state changes, proving highly useful for asynchronous operations like API calls. Users can easily manage the state change function (mutate), current state (state), loading state (loading), and any errors (error) that occur.

  3. Improved State Change Detection in useStateSubscription: The useStateSubscription has been improved for more refined detection of state changes. The callback function now maintains the latest state, accurately detecting and responding to state changes.

  4. Enhanced TypeScript Support: The hooks.d.ts file has been updated to supplement the TypeScript definitions for all hooks. useStateQuery and useStateMutation use the StateQueryResult and StateMutationResult interfaces, respectively, to clearly define their return types. These definitions assist developers in using the hooks more accurately and safely.

  5. Enhanced Asynchronous Processing in updateState: The updateState function now allows for asynchronous state updates. This function updates a state and all its dependent states using an appropriate traversal strategy (DFS or BFS). These changes offer the following advantages:

5-1. Asynchronous State Management: The updateState function returns a Promise, allowing asynchronous waiting for the completion of state updates. This is especially useful in integrating external asynchronous operations like API calls.

5-2. Dependent State Updates: Considering the dependencies between states, an update to one state automatically reflects in all its dependent states. This facilitates easier management of complex state relationships.

5-3. DFS and BFS Strategies: The strategy for state updates, whether DFS (Depth-First Search) or BFS (Breadth-First Search), is determined based on the relationships between states. This allows for the selection of the most efficient update strategy according to the state structure.

  • This update strengthens and makes state management more flexible by integrating asynchronous operations, managing complex state relationships, and optimizing state update strategies. These improvements will be particularly effective in interactions with external data sources and handling complex state dependencies.

🦊 Example Usage (Ver 2.8.1 ~ ): 🦊

  1. child.js
import React from 'react';
import { useStateMutation, updateState, registerFunction } from 'quickrenard';

function Child() {
  // Using useStateMutation to manage 'childData.data' state.
  // This hook returns the current state value.
  const { state: data } = useStateMutation('childData.data');

  const handleUpdateData = () => {
    const newData = "Updated Data from Child";

    // Calling the asynchronous updateState function to update 'childData.data'.
    // It returns a Promise, allowing us to handle the completion or failure of the update.
    updateState('childData.data', newData)
      .then(() => {
        // Logging on successful state update.
        console.log("State and dependent states updated with the appropriate strategy");
      })
      .catch(err => {
        // Logging in case of an error.
        console.error("Error updating state:", err);
      });
  };

  // Registering a function 'childFunction' that can be called by the Cousin component.
  // This function logs a message received from the Cousin component.
  registerFunction('childFunction', (message) => {
    console.log("Message from Cousin:", message);
    return "Response from Child";
  });

  return (
    <div>
      <h3>Child Component</h3>
      <p>Data: {data}</p>
      <button onClick={handleUpdateData}>Update Data</button>
    </div>
  );
}

export default Child;
  1. cousin.js
import React, { useEffect, useState } from 'react';
import { useStateQuery, useStateSubscription } from 'quickrenard';

function Cousin() {
  // Use useStateQuery to manage the state of 'childData.data'.
  // This hook returns an object with { data, loading, error } for 'childData.data'.
  const { data: childData, loading: childLoading, error: childError } = useStateQuery('childData.data');

  // Use useStateQuery to manage the state of 'parentData'.
  // The hook fetches the current state of 'parentData'.
  const { data: parentData } = useStateQuery('parentData');

  // Use useStateQuery to manage the state of 'siblingData'.
  // The hook fetches the current state of 'siblingData'.
  const { data: siblingData } = useStateQuery('siblingData');

  // Local states to display data, initialized with the data from useStateQuery.
  const [displayedChildData, setDisplayedChildData] = useState(childData);
  const [displayedParentData, setDisplayedParentData] = useState(parentData);
  const [displayedSiblingData, setDisplayedSiblingData] = useState(siblingData);

  // Subscribe to changes in 'childData.data' and update displayedChildData accordingly.
  // This will re-render the component with new child data when it changes.
  useStateSubscription('childData.data', (newData) => {
    console.log("Child data has changed!");
    setDisplayedChildData(newData);
  });

  // Subscribe to changes in 'parentData' and update displayedParentData accordingly.
  // This will re-render the component with new parent data when it changes.
  useStateSubscription('parentData', (newData) => {
    console.log("Parent data has changed!");
    setDisplayedParentData(newData);
  });

  // Subscribe to changes in 'siblingData' and update displayedSiblingData accordingly.
  // This will re-render the component with new sibling data when it changes.
  useStateSubscription('siblingData', (newData) => {
    console.log("Sibling data has changed!");
    setDisplayedSiblingData(newData);
  });

  // useEffect to log when Cousin component mounts.
  // Useful for checking if the component is correctly mounted.
  useEffect(() => {
    console.log('Cousin mounted.');
  }, []);

  // Render the loading state, error state, or the actual data from childData, parentData, and siblingData.
  return (
    <div>
      <h3>Cousin Component</h3>
      <p>Child Data: {childLoading ? 'Loading...' : childError ? childError.message : displayedChildData}</p>
      <p>Parent Data: {displayedParentData}</p>
      <p>Sibling Data: {displayedSiblingData}</p>
    </div>
  );
}

export default Cousin;
  1. stateSchema.js
export const stateSchema = {
    'childData.data': {
        type: 'string',
        defaultValue: 'Initial Child Data',
        dependencies: ['parentData', 'siblingData']
    },
    'parentData': {
        type: 'string',
        defaultValue: 'Initial Parent Data'
    },
    'siblingData': {
        type: 'string',
        defaultValue: 'Initial Sibling Data'
    }
};
  1. stateStore.js
// stateStore.js
import { initializeStore, getCacheObject, setStateDependencies } from 'quickrenard';
import { stateSchema } from './stateSchema';

// Define state dependencies
const dependencies = {
    'childData.data': ['parentData', 'siblingData'],
};

// Initialize Store
// Example: Set cache expiration time to 30 minutes
initializeStore(stateSchema, { cacheExpirationTime: 1800000 });

// // Set state dependencies
setStateDependencies(dependencies);

/** 🦊Optional Usage Example🦊: Function for cache expiration countdown */

// Function for cache expiration countdown
function cacheExpirationCountdown() {
  // Get the current time
  const now = performance.now();

  // Access the cache object
  const cache = getCacheObject();

  console.clear();
  console.log("Cache Expiration Countdown:");

  // Iterate through each cache key and display the remaining time
  Object.keys(cache).forEach(key => {
    const record = cache[key];
    if (record) {
      const remainingTime = record.expirationTime - now;
      if (remainingTime > 0) {
        console.log(`${key}: ${Math.ceil(remainingTime / 1000)} seconds remaining`);
      } else {
        console.log(`${key}: Expired`);
      }
    }
  });
}

// 🦊Optionally, run the countdown periodically🦊
setInterval(cacheExpirationCountdown, 1000);

Adjust your component implementations as necessary to align with these examples and the unique details of your project. This documentation is designed to provide a conceptual understanding of QuickRenard's enhanced functionality.

🦊License🦊

  • This project is licensed under the MIT License - see the LICENSE.md file for details.
2.8.3

4 months ago

2.8.1

5 months ago

2.8.0

5 months ago

2.8.2

5 months ago

2.7.4

5 months ago

2.7.3

5 months ago

2.7.6

5 months ago

2.7.5

5 months ago

2.7.2

6 months ago

2.7.1

6 months ago

2.7.0

6 months ago

2.6.5

6 months ago

2.6.4

6 months ago

2.6.3

6 months ago

2.6.2

6 months ago

2.6.1

6 months ago

2.6.0

6 months ago

2.5.9

6 months ago

2.5.8

6 months ago

2.5.7

6 months ago

2.5.6

6 months ago

2.5.5

6 months ago

2.5.4

6 months ago

2.5.3

6 months ago

2.5.2

6 months ago

2.5.1

6 months ago

2.5.0

6 months ago

2.4.6

6 months ago

2.4.5

6 months ago

2.4.4

6 months ago

2.4.3

6 months ago

2.4.2

6 months ago

2.4.1

6 months ago

2.4.0

6 months ago

2.3.1

6 months ago

2.3.0

6 months ago

2.2.10

6 months ago

2.2.9

6 months ago

2.2.8

6 months ago

2.2.7

6 months ago

2.2.6

6 months ago

2.2.5

6 months ago

2.2.4

6 months ago

2.2.3

6 months ago

2.2.2

6 months ago

2.2.1

6 months ago

2.2.0

6 months ago

2.1.7

6 months ago

2.1.6

6 months ago

2.1.5

6 months ago

2.1.4

6 months ago

2.1.3

6 months ago

2.1.2

6 months ago

2.1.1

6 months ago

2.1.0

6 months ago

2.0.24

6 months ago

2.0.23

6 months ago

2.0.22

6 months ago

2.0.21

6 months ago

2.0.20

6 months ago

2.0.19

6 months ago

2.0.18

6 months ago

2.0.17

6 months ago

2.0.16

6 months ago

2.0.15

6 months ago

2.0.14

6 months ago

2.0.13

6 months ago

2.0.12

6 months ago

2.0.11

6 months ago

2.0.10

6 months ago

2.0.9

6 months ago

2.0.8

6 months ago

2.0.7

6 months ago

2.0.6

6 months ago

2.0.5

6 months ago

2.0.4

6 months ago

2.0.3

6 months ago

2.0.2

6 months ago

2.0.1

6 months ago

2.0.0

6 months ago

1.2.0

7 months ago

1.1.14

7 months ago

1.1.13

7 months ago

1.1.12

7 months ago

1.1.11

7 months ago

1.1.10

7 months ago

1.1.9

7 months ago

1.1.8

7 months ago

1.1.7

7 months ago

1.1.6

7 months ago

1.1.5

7 months ago

1.1.4

7 months ago

1.1.3

7 months ago

1.1.2

7 months ago

1.1.1

7 months ago

1.1.0

7 months ago

1.0.15

7 months ago

1.0.14

7 months ago

1.0.13

7 months ago

1.0.12

7 months ago

1.0.11

7 months ago

1.0.10

7 months ago

1.0.9

7 months ago

1.0.8

7 months ago

1.0.7

7 months ago

1.0.6

7 months ago

1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

7 months ago

1.0.2

7 months ago

1.0.1

7 months ago

1.0.0

7 months ago