Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Releases: glyph-cat/react-relink

4.3.2

Choose a tag to compare

@glyph-cat glyph-cat released this 03 Jun 04:04
  • Updated README with deprecation message.

4.3.1

Choose a tag to compare

@glyph-cat glyph-cat released this 03 Jun 04:01
  • This package has been deprecated in favor of cotton-box, which has a similar API design to React Relink. For information on migrating, please refer to the Migration Guide.

4.3.0

Choose a tag to compare

@glyph-cat glyph-cat released this 12 May 15:50
  • New experimental hook useRelinkSource that allows creation of RelinkSource inside a React component and disposes it when the component is unmounted.

4.2.2

Choose a tag to compare

@glyph-cat glyph-cat released this 08 Apr 16:39

This release contains a bug fix for useRelinkValue where the state is returned as null if the active parameter is set to false in the beginning.


Consider the code below:

import { useState, useEffect } from 'react'
import { RelinkSource, useRelinkValue } from 'react-relink'

const SomeSource = new RelinkSource({
  key: 'some-source',
  default: 42,
})

function App(): JSX.Element {
  const [active, setActive] = useState(false)
  const someState = useRelinkValue(SomeSource, null, active)
  useEffect(() => { setActive(true) }, [])
  console.log(someState)
  return <h1>Hello world</h1>
}

Before fix:

Render cycle active someState Is expected value?
First false null ❌ No
Second true 42 ✅ Yes

After fix:

Render cycle active someState Is expected value?
First false 42 ✅ Yes
Second true 42 ✅ Yes

4.2.1

Choose a tag to compare

@glyph-cat glyph-cat released this 02 Apr 10:12
  • Fixed a bug in useRelinkValue where selectors are not being executed during server-side rendering
  • Updated project dependencies

4.2.0

Choose a tag to compare

@glyph-cat glyph-cat released this 10 Nov 14:27
  • The default state of a source is now made accessible in hydration callbacks via the defaultState property
Source.hydrate(({ commit, defaultState }) => {
  commit({ ...defaultState, ...fetchedState })
})
  • Fixed typing mistakes in some debugging messages
  • Stability enhancements for edge cases that involve dynamic imports

4.1.0

Choose a tag to compare

@glyph-cat glyph-cat released this 16 Oct 16:11

Bug fixes

  • Fixed issue where child dependencies with source keys of type symbol were not checked against when calling .cleanup() on the parent source, resulting in a false negative where no warnings are displayed.

API Changes

  • key and default are now exposed as read-only properties of the RelinkSource class. This way, it is no longer needed to go through the additional trouble of importing/exporting them when needed because they are already accessible through the source instance.
  • Deprecated .cleanup() in favor of .dispose().
  • By default, .dispose() will wait for all queued actions to complete before actually disposing a source. There is a force option that can bypass that, but it is strictly intended for being used in teardown functions in tests only.
  • For hydration, skip is deprecated and replaced by commitDefault. There is also a new hydration strategy called commitNoop to complete the hydration without triggering any state changes.
  • useRelinkValue(...) now accepts a third argument to control whether the hook should listen for state changes
// Without selector
useRelinkValue(Source, null, true /* or false */ )
// With selector
useRelinkValue(Source, selector, true /* or false */ )

Miscellaneous

  • Improved documentation in the TypeScript definition file as well as runtime messages for debugging (development env only) for more clarity.
  • Compilation target of this package has been set to ES2020.

Known Issues

  • In the examples of .cleanup() and .dispose() in the .d.ts file, creating sources in the render phase then disposing them in cleanup effects in StrictMode will cause an error. Indeed, eventually, the source is created and disposed twice, just as inteneded by Strict Mode, but the order in which they are created and disposed seems to be jumbled up.
    • Demonstration:
      • Clone the repository, run yarn install, then run yarn playground:web
      • Navigate to http://localhost:3000/dynamic-create-dispose
      • During initial render, everything seems fine
      • Click on "Increase counter", a TypeError will be thrown.
    • Intended behaviour:
      • 1st render phase: Source is created
      • 1st Cleanup phase: Source is disposed
      • 2nd render phase: Source is created
    • Actual behaviour:
      • 1st render phase: Source is created
      • 2nd render phase: Source is created
      • 1st Cleanup phase: Source is disposed

4.0.1

Choose a tag to compare

@glyph-cat glyph-cat released this 06 Sep 08:50
  • Updates made to some inline documentations
  • Internal optimizations
    • Fixed typo in test file
    • Updated tsconfig.json

4.0.0

Choose a tag to compare

@glyph-cat glyph-cat released this 21 May 05:15

Support for Concurrent Rendering

This version adds compatibility for React 18's concurrent rendering by using the useSyncExternalStore hook.


Deprecated option: virtualBatch

Previously, Relink implements its own hook to subscribe to sources, watch for state changes, then decide if a component should update; but with useSyncExternalStore, Relink no longer has control over when to trigger component updates.

On the flipside, even though there is no 1:1 substitution, concurrent rendering might just be able to solve the problem virtualBatch has been trying to solve since day one — to make it possible to defer component updates for complicated states.

In fact, concurrent rendering provides a more granular control: in a sense that you can now tell React which "set state" calls are urgent and which ones are not, instead of only distinguishing them by sources.


Note: Basic selectors do not need to be memoized

// ✅ OK
function SomeComponent(): JSX.Element {
  const someState = useRelinkValue(SomeSource, (state) => state.foo)
  return /* ... */
}
// ✅ Also OK
// Ideal for sharing with components in other files in a consistently manner.
export const someSelector = (state) => state.foo

function SomeComponent(): JSX.Element {
  const someState = useRelinkValue(SomeSource, someSelector)
  return /* ... */
}
// ❌ Unnecessary
function SomeComponent(): JSX.Element {
  const selector = useCallback((state) => state.foo, [])
  const someState = useRelinkValue(SomeSource, selector)
  return /* ... */
}

Removal of deprecated APIs

These APIs are marked as deprecated in the previous version and is no longer included in this version.

  • (deprecated -> new)
  • createSource -> new RelinkSource(...)
  • isRelinkSource -> value instanceof RelinkSource

New exposed constants

(Probably rarely used)

  • BUILD_HASH
  • BUILD_TYPE
  • RelinkBuildType

3.1.3

Choose a tag to compare

@glyph-cat glyph-cat released this 17 Feb 08:39
  • Hotfix for issue where a re-render might be triggered for components using useRelinkValue even after they have been unmounted.