@huds0n/shared-state
v2.0.0-beta1
Published
Global State Manager for React Native
Downloads
59
Maintainers
Readme
📝 Table of Contents
🧐 About
Global state management is one of the core aspects of nearly all React Native projects, especially as they grow in size.
Shared States solves this problem by declaring your shared state variables outside of your components. Then, using familiar syntax to React, registering components for updates on shared state change.
✅ List of Features
- Simple: Uses similar structure and syntax to standard React.
- Fast: Optimize components to only update when is necessary.
- Powerful: Seemlessly integrate state change with both UI and logic.
- Versatile: Have a single global state, or split it in multiple shared states.
- Persistant: Combine with a Shared State Store to presist data.
- Type-Safe: Fully integrated with typescript out-of-the-box.
🏁 Getting Started
Prerequisites
Works with any project implementing React 16.8 onwards
Installing
npm i @huds0n/shared-state
🧑💻 Basic Usage
Creating a Shared State
import { SharedState } from "@huds0n/shared-state";
const ExampleState = new SharedState({
username: null,
password: null
...ect
});
Accessing State
const { username, password } = ExampleState.state;
Updating State
Like regular state, direct mutation will not cause components to update. Instead the setState method is used.
ExampleState.setState({
username: "john.doe",
password: "******",
});
setState can take either the whole or a partial state, updating only the props that are passed. Like regular state, Shared State uses shallow comparison to detect state changes.
Function Components Integration
function exampleFunctionComponent() {
const [state, setState] = ExampleState.useState();
// Or if you want to be more specific
const [username, setUsername] = ExampleState.useProp("username");
}
Class Components Integration
componentDidMount() {
ExampleState.register(this);
}
componentWillUnmount() {
ExampleState.unregister(this);
}
🧑🔬 Advanced Usage
Update Keys
Registration of a component to a shared state causes automatic re-rendering on any state change. To select specific props to cause re-render an update key (string) or keys (array of strings) can be passed to the register and useState methods.
ExampleState.register(this, "username");
This class component would only update on username change.
Example.useState(["username", "password"]);
This function component would update on either username or password change.
State Listeners
State changes can be used to trigger logic as well.
const removeListener = ExampleState.addListener(
(newState, prevState) => {
if (prevState.user === null) {
// Runs when user changes from null
}
},
["username"]
);
Then to remove the listener.
removeListener();
Using Typescript
Shared State has been built from the ground up to use typescript. It will predict state type structure automatically from the initial state. However, in cases where state props can be multiple types you will need to pass in declarative typings when instantiating the state.
type ExampleStateType = {
username: null | string,
password: null | string,
...ect
}
const ExampleState = new SharedState<ExampleStateType>({
username: null,
password: null,
...ect
});
📖 Reference
Properties
| Prop | Description | Type | | ------------------------- | ------------------------------------------------------------------------ | ----------------------------------------- | | state | current state | state object | | prevState | previous state(undefined if no state change yet has occurred) | state objector undefined |
Methods
| Methods/Param | Description | Return/Type | | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | --- | --- | | addListener | Adds listener to trigger on state changes Returns remove listener function | () => boolean | | callback | Called everytime the trigger changes occur | (current: State, prev: Partial State) => void | | trigger (optional) | Defines which state changes the listener triggers on | Update Key | | | | | | | | refresh | Forces registered components to re-render | - | | refreshKeys (optional) | Limits refresh to components registered with specific keys | Update Key | | | | | | register | Registers class components to re-render on state changeUse in either constructor or componentDidMount methods | - | | component | To link the class component this needs to be passed into the function | this | | updateKey(s) (optional) | If present then the component will only re-render on key trigger | Update Key | | | | | | removeAllListeners | Clears all listeners started by the addListener method | - | | | | | | reset | Resets state back to the default stateDeletes or updates stored state depending on reset state | - | | resetState (optional) | If present, becomes the State's new default state | State | | | | | | | | | setProp | Update a single property of the stateShallow comparison is used to detect/trigger re-renders | - | | propName | Defines which property to update | key of State | | newValue | Property's new value | propType | | | | | | setState | Updates state by combining the newState with the current stateShallow comparison evaluates updated stateUpdated state triggers re-renders and is returned | Partial State | | newState | The new state to _ | key of State | | newValue | Property's new value | propType | | | | | | toString | Returns the current state in as a JSON string | string | | | | | | unregister | Un-registers class components from re-rendering on state changeUse in componentWillMount methodsFailure of this will result in memory leaks | - | | component | To un-link the class component this needs to be passed into the function | this | | | | | useProp | Hook to register functional component to StateReturns array of prop value and prop setter, similar to useState | [prop, setPropFn] | | updateKey(s) (optional) | If present then the component will only re-render on key trigger | **Update Key** | | | | | | useState | Hook to register functional component to StateReturns array of state and state setterAllows additional optimization with the shouldUpdate param | [state, setStateFn] | | updateKey(s) (optional) | If present then the component will only re-render on key trigger | **Update Key_** | | shouldUpdateFn(optional) | Run when triggered by StateThe component will on then update if function return true | (newState: State, prevState: Partial State) => boolean |
📲 Example
Clone or fork the repo at https://github.com/JontiHudson/modules-huds0n-shared-state
Go to the __example__ folder. Run npm install to install the expo project, then expo start to launch the example.
✍️ Authors
- @JontiHudson - Idea & Initial work
- @MartinHudson - Support & Development
See also the list of contributors who participated in this project.
🎉 Acknowledgements
- Special thanks to my fiance, Arma, who has been so patient with all my extra-curricular work.