Migration From react-relink
info
The usage of .get
, .set
, .reset
, and .dispose
remains the same.
Setup
Before
yarn add react-relink
Now
yarn add cotton-box cotton-box-react
Instantiation
Before
import { RelinkSource } from 'react-relink'
const ExampleSource = new RelinkSource({
key: 'example-source',
default: 'defaultState',
lifecycle: {
init({ commit, commitNoop, defaultState }) {
// ...
},
didSet({ state }) {
// ...
},
didReset() {
// ...
},
},
options: {
suspense: true | false,
public: true | false,
},
scope: OtherSource,
})
Now
import { AsyncStateManager, StateManagerVisibility } from 'cotton-box'
// Default state is passed as first parameter,
// remaining options are passed as the second.
const ExampleState = new AsyncStateManager('defaultState', {
// `key` is no longer needed, but there is a `name` property,
// which is *optional* and only used for debugging.
lifecycle: {
init({ commit, commitNoop, defaultState }) {
// ...
},
// `defaultState` is exposed here:
didSet({ state, defaultState }) {
// ...
},
didReset() {
// ...
},
},
// New option:
clientOnly: true | false,
// `visibility` is a boolean type in react-relink:
visibility: StateManagerVisibility.ENVIRONMENT,
suspense: true | false,
// Scope is not supported by Cotton Box
})
Consuming the State
Before
function App() {
import { useRelinkValue } from 'react-relink'
const state = useRelinkValue(ExampleSource)
return '...'
}
Now
function App() {
import { useStateValue } from 'cotton-box-react'
const state = useStateValue(ExampleState)
return '...'
}
Handling dependencies
Before
const ExampleSourceA = new RelinkSource({
key: 'example-source-a',
default: '...',
lifecycle: { /* ... */ },
})
const ExampleSourceB = new RelinkSource({
key: 'example-source-b',
default: '...',
deps: [ExampleSourceA],
lifecycle: { /* ... */ },
})
Now
const ExampleStateA = new StateManager('...')
const ExampleStateB = new StateManager('...', {
lifecycle: {
init() {
await ExampleStateA.isInitializing.wait(false)
// continue to do something
},
},
})
Re-initialization
Before
MySource.hydrate(...)
Now
ExampleState.init(...)
Scope
Cotton Box does not have Scope-related APIs to reduce complexity. Instead, we recommend using React's Context API as a substitute as it allows more fine-grained control at the same time.