2.0.0-beta1 • Published 1 year ago

@huds0n/shared-state v2.0.0-beta1

Weekly downloads
252
License
MIT
Repository
-
Last release
1 year ago

Status GitHub Issues GitHub Pull Requests License


📝 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

PropDescriptionType
statecurrent statestate object
prevStateprevious state(undefined if no state change yet has occurred)state objector undefined

Methods

Methods/ParamDescriptionReturn/Type
addListenerAdds listener to trigger on state changes Returns remove listener function() => boolean
callbackCalled everytime the trigger changes occur(current: State, prev: Partial State) => void
trigger (optional)Defines which state changes the listener triggers onUpdate Key
refreshForces registered components to re-render-
refreshKeys (optional)Limits refresh to components registered with specific keysUpdate Key
registerRegisters class components to re-render on state changeUse in either constructor or componentDidMount methods-
componentTo link the class component this needs to be passed into the functionthis
updateKey(s) (optional)If present then the component will only re-render on key triggerUpdate Key
removeAllListenersClears all listeners started by the addListener method-
resetResets state back to the default stateDeletes or updates stored state depending on reset state-
resetState (optional)If present, becomes the State's new default stateState
setPropUpdate a single property of the stateShallow comparison is used to detect/trigger re-renders-
propNameDefines which property to updatekey of State
newValueProperty's new valuepropType
setStateUpdates state by combining the newState with the current stateShallow comparison evaluates updated stateUpdated state triggers re-renders and is returnedPartial State
newStateThe new state to key of State
newValueProperty's new valuepropType
toStringReturns the current state in as a JSON stringstring
unregisterUn-registers class components from re-rendering on state changeUse in componentWillMount methodsFailure of this will result in memory leaks-
componentTo un-link the class component this needs to be passed into the functionthis
usePropHook to register functional component to StateReturns array of prop value and prop setter, similar to useStateprop, setPropFn
updateKey(s) (optional)If present then the component will only re-render on key triggerUpdate Key
useStateHook to register functional component to StateReturns array of state and state setterAllows additional optimization with the shouldUpdate paramstate, setStateFn
updateKey(s) (optional)If present then the component will only re-render on key triggerUpdate 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

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.
2.0.0-beta1

1 year ago

1.6.0-beta53

2 years ago

1.6.0-beta54

2 years ago

1.6.0-beta60

2 years ago

1.6.0-beta61

2 years ago

1.6.0-beta63

2 years ago

1.6.0-beta46

2 years ago

1.6.0-beta47

2 years ago

1.6.0-beta48

2 years ago

1.6.0-beta49

2 years ago

1.6.0-beta42

2 years ago

1.6.0-beta44

2 years ago

1.6.0-beta45

2 years ago

1.6.0-beta50

2 years ago

1.6.0-beta51

2 years ago

1.6.0-beta52

2 years ago

1.6.0-beta35

2 years ago

1.6.0-beta36

2 years ago

1.6.0-beta37

2 years ago

1.6.0-beta38

2 years ago

1.6.0-beta31

2 years ago

1.6.0-beta40

2 years ago

1.6.0-beta26

2 years ago

1.6.0-beta13

2 years ago

1.5.1-beta3

3 years ago

1.5.1-beta.1

3 years ago

1.5.1-beta.2

3 years ago

1.5.0-beta.21

3 years ago

1.5.0-beta.20

3 years ago

1.5.0-beta.16

3 years ago

1.5.0-beta.15

3 years ago

1.5.0-beta.14

3 years ago

1.5.0-beta.13

3 years ago

1.4.6

3 years ago

1.4.5

3 years ago

1.4.4

3 years ago

1.4.3

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.4-beta.4

3 years ago

1.3.4-beta.3

3 years ago

1.3.4-beta.2

3 years ago

1.3.4-beta.1

3 years ago

1.3.3-beta.7

3 years ago

1.3.3-beta.5

3 years ago

1.3.3-beta.4

3 years ago

1.3.3-beta.6

3 years ago

1.3.3-beta.3

3 years ago

1.3.3-beta.2

3 years ago

1.3.2-beta.8

3 years ago

1.3.2-beta.7

3 years ago

1.3.2-beta.6

3 years ago

1.3.2-beta.5

4 years ago

1.3.2-beta.4

4 years ago

1.3.2-beta.3

4 years ago

1.3.2-beta.1

4 years ago

1.3.1-beta.24

4 years ago

1.3.1-beta.23

4 years ago

1.3.1-beta.21

4 years ago

1.3.1-beta.22

4 years ago

1.3.1-beta.20

4 years ago

1.3.1-beta.16

4 years ago

1.3.1-beta.17

4 years ago

1.3.1-beta.15

4 years ago

1.3.1-beta.11

4 years ago

1.3.1-beta.9

4 years ago

1.3.1-beta.7

4 years ago

1.3.1-beta.6

4 years ago

1.3.0-beta.22

4 years ago

1.3.0-beta.21

4 years ago

1.3.0-beta.20

4 years ago

1.3.0-beta.18

4 years ago

1.3.0-beta.19

4 years ago

1.3.0-beta.17

4 years ago

1.3.0-beta.15

4 years ago

1.3.0-beta.16

4 years ago

1.3.0-beta.13

4 years ago

1.3.0-beta.12

4 years ago

1.3.0-beta.10

4 years ago

1.3.0-beta.7

4 years ago

1.2.0-beta.20

4 years ago

1.3.0-beta.2

4 years ago

1.3.0-beta.3

4 years ago

1.3.0-beta.4

4 years ago

1.3.0-beta.5

4 years ago

1.3.0-beta.6

4 years ago

1.2.0-beta.19

4 years ago

1.2.0-beta.18

4 years ago

1.2.0-beta.17

4 years ago

1.2.0-beta.16

4 years ago

1.2.0-beta.15

4 years ago

1.2.0-beta.12

4 years ago

1.2.0-beta.14

4 years ago

1.2.0-beta.13

4 years ago

1.2.0-beta.9

4 years ago

1.2.0-beta.8

4 years ago

1.2.0-beta.7

4 years ago

1.2.0-beta.6

4 years ago

1.2.0-beta.3

4 years ago

1.2.0-beta.2

4 years ago

1.2.0-beta.5

4 years ago

1.2.0-beta.4

4 years ago

1.3.0-beta.1

4 years ago

1.2.0

4 years ago

1.1.0

4 years ago

1.0.0

4 years ago