Key features:
- Components don't need to be wrapped in Providers
- States can be shared across different React components trees
- Supports asynchronous "setState" functions
- Declarative lifecycle management
Installation
With Yarn
yarn add react-relink
With NPM:
npm i react-relink
Usage
Note: you can find a more detailed documentation in the TypeScript definition file which is located at <your-project>/node_modules/react-relink/lib/types/index.d.ts
.
Create a Source
Provide a default state for the source.
import { RelinkSource } from 'react-relink'
const CounterSource = new RelinkSource({
key: 'counter',
default: 1,
})
Consume a Source
You can work with the sources right away without needing to wrap your app inside any provider components. This makes accessing them across different React component trees very easy, such as when registering screen components in React Native Navigation.
To consume a source, pass it as a parameter into any of the following Relink hooks:
-
useRelinkState
- returns the state value, a setter, and a resetter function. -
useSetRelinkState
- returns just the setter function of the state. -
useRelinkValue
- returns just the value of the state. -
useResetRelinkState
- returns a function that sets the state to its default value. -
useHydrateRelinkSource
- returns a function that sets the state without invoking thedidSet
lifecycle method.
An example with the useRelinkState
hook:
function App() {
const [counter, setCounter, resetCounter] = useRelinkState(CounterSource)
// `setCounter` accepts either a value to replace the state or a reducer
return (
<div>
<span>Counter: {counter}</span>
<button onClick={() => {
// Value
setCounter(5)
}}>Set to 5</button>
<button onClick={() => {
// Reducer
setCounter((oldCounter) => {
const newCounter = oldCounter + 1
return newCounter
})
}}>Step up</button>
<button onClick={resetCounter}>Reset</button>
</div>
)
}
Examples with other hooks:
const counter = useRelinkValue(CounterSource)
console.log('Counter is ' + counter)
const setCounter = useSetRelinkState(CounterSource)
setCounter(/* new value */)
const resetCounter = useResetRelinkState(CounterSource)
resetCounter()
const rehydrateCounter = useHydrateRelinkSource(CounterSource)
rehydrateCounter(({ commit, skip }) => {
const persistedState = custom_method_to_fetch_persisted_state()
if (persistedState) {
commit(persistedState)
} else {
skip()
}
})
Error Codes
In production builds, error codes are thrown instead of the lengthy messages to save data.
-
Relink_E1-typeofRawKey
— Expectedkey
to be a string or number but got${typeofRawKey}
-
Relink_E2-depStack
— Circular dependencies are not allowed:${depStack}
-
Relink_E3-marker
- Internal error: malformed hydration marker '${marker}
'
List of Breaking Changes
Support This Project
- Ko-fi:
ko-fi.com/glyphcat
- BTC:
bc1q5qp6a972l8m0k26ln9deuhup0nmldf86ndu5we
Miscellaneous
Looking for a specialized package to handle localizations? Check out Langutil.