Gathering detailed insights and metrics for use-oo-state
Gathering detailed insights and metrics for use-oo-state
Gathering detailed insights and metrics for use-oo-state
Gathering detailed insights and metrics for use-oo-state
This package aims to solve the problems of complex states in React's functional components. While functional programming in React has many perks, managing a complex state can get messy. Combining the many benefits of object-oriented programming with React's functional programming makes splitting up code and responsibility among classes easier. This makes it easier to create and maintain clean code.
npm install use-oo-state
v.0.0.19
Published on 23 Oct 2022
v.0.0.18
Published on 23 Oct 2022
Mutate initial state and props
Published on 23 Oct 2022
add resetState method
Published on 27 Apr 2022
Fix onStateUpdated and onPropsUpdated call
Published on 27 Apr 2022
call onCreated hook after initalisation
Published on 11 Apr 2022
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
35 Commits
1 Watching
1 Branches
1 Contributors
Updated on 10 Apr 2022
TypeScript (84.34%)
CSS (8.23%)
HTML (4.59%)
JavaScript (2.84%)
Cumulative downloads
Total Downloads
Last day
-56.5%
10
Compared to previous day
Last week
37.7%
106
Compared to previous week
Last month
27.5%
292
Compared to previous month
Last year
9.2%
4,090
Compared to previous year
This package aims to solve the problems of complex states in React's functional components. While functional programming in React has many perks, managing a complex state can get messy. Combining the many benefits of object-oriented programming with React's functional programming makes splitting up code and responsibility among classes easier. This makes it easier to create and maintain clean code.
npm i use-oo-state
1import { useOOState } from 'use-oo-state' 2 3const [state, exampleManager, props] = useOOState(ExampleStateManager, initialState, props)
This package is useful in higher order components or contexts, where the state tends to get messy. This package will make it easy to create fully typed classes to manipulate the state object.
This package is an early version, and might have performance impact.
This package consists of three main concepts:
The package holds its own internal state, which ensures that the state version always is the latest when accessed. Therefore, you don't have to pass arguments into methods to access the latest state, instead you can access it directly with this.state
when you need it. Under the hood it uses useState
to update the reactive state.
StateManager is a generic class that will be extended per state you want to use OO State for. It takes two generic arguments: state and props.
First we need to create an interface for the state and for the props:
1interface ExampleState { 2 name: string 3 nameErrorMessage: string 4 email: string 5} 6 7interface ExampleProps { 8 userId: string 9}
Then we create our new StateManager in a TS file:
1import { StateManager } from 'use-oo-state' 2 3export class ExampleStateManager extends StateManager<ExampleState, ExampleProps> { 4 5}
This class exposes the state on this.state
. The state is mutable and should be updated with a call to this.setState()
.
The setState method accepts a partial version of the state, e.g.: this.setState({ name: 'newName' })
. this.state
and this.setState
is also directly
accessible in SubStateHandlers.
If you ever want to reset the whole state to the initial state, the state manager also exposes the this.resetState()
method.
That method will reset the state to the initialState and call the onCreated
hook.
This class exposes the following lifecycle hooks that can be overriden:
1import { StateManager } from 'use-oo-state' 2 3export class ExampleStateManager extends StateManager<ExampleState, ExampleProps> { 4 override onCreated = () => { 5 console.log('The manager was created') 6 } 7 8 override onBeforeStateUpdated = (newState: Partial<ExampleState>, oldState: ExampleState) => { 9 console.log('The class is about to update with the following state: ', newState) 10 return newState 11 } 12 13 override onStateUpdated = (newState: Partial<ExampleState>, oldState: ExampleState) => { 14 console.log('The state is updated with the following state: ', newState) 15 } 16 17 override onPropsUpdated = (newProps: Partial<ExampleProps>, oldProps: Partial<ExampleProps>) => { 18 console.log(`The class received new props: ${newProps}`) 19 } 20}
A SubStateHandler is used to handle code for the state manager. A state manager can have multiple substate handlers. It can have internal state that is not reactive, and has access to the reactive state of the StateManager. In this example, we will use two handlers:
1import { SubStateHandler } from 'use-oo-state' 2 3export class ExampleNameHandler extends SubStateHandler<ExampleStateManager> { 4 5 readonly updateName = (newName: string) => { 6 if (!this.state.name) console.log('No name set') // The state of the StateManager is accessible on this.state 7 this.setState({ name: newName )} // To update the state of the StateManager use this.setState 8 } 9 10 readonly checkNameIsMatchingEmail = (email: string, name: string) => { 11 return !email.toLowerCase().includes(names) 12 } 13}
1import { SubStateHandler } from 'use-oo-state' 2 3export class ExampleEmailHandler extends SubStateHandler<ExampleStateManager> { 4 5 readonly updateEmail = (newEmail: string) => { 6 this.setState({ email: newEmail }) // To update the state of the StateManager use this.setState 7 } 8}
We then need to initialise the SubStateHandlers in the StateManager:
1export class ExampleStateManager extends StateManager<ExampleState, ExampleProps> { 2 readonly nameHandler = new ExampleNameHandler(this) 3 readonly emailHandler = new ExampleEmailHandler(this) 4}
If we want to listen to the life cycle hooks:
1 export class ExampleStateManager extends StateManager<ExampleState, ExampleProps> { 2 readonly nameHandler = new ExampleNameHandler(this) 3 readonly emailHandler = new ExampleEmailHandler(this) 4 5 override onBeforeStateUpdated = (newState: Partial<ExampleState>, oldState: ExampleState) => { 6 if (newState.email) { 7 const name = newState.email ?? oldState.email 8 if (!this.nameHandler.checkNameIsMatchingEmail(newState.email, name)) { 9 newState.nameErrorMessage = 'Name is not matching email' 10 } 11 } 12 return newState 13 } 14 15 override onPropsUpdated = (newProps: Partial<ExampleProps>, oldProps: ExampleProps) => { 16 if (newProps.userId !== oldProps.userId) { 17 console.log('User have changed, should probably do some resetting here') 18 } 19 } 20}
The useOOState is the connection between React and the Object Oriented State. It is used as a normal hook:
1import { useOOState } from 'use-oo-state' 2 3const [state, exampleManager, props] = useOOState(ExampleStateManager, initialState, { userId: '1' })
Then it can be used in a component or a context:
In component:
1interface ExampleComponentProps { 2 userId: string 3} 4 5const initialState: ExampleState = { 6 name: '', 7 email: '', 8 nameErrorMessage: '' 9} 10 11const ExampleComponent: React.FC<ExampleComponentProps> = ({ userId }) => { 12 const [state, exampleManager, props] = useOOState(ExampleStateManager, initialState, { userId }) 13 14 return ( 15 <div> 16 <div> 17 Hello, {state.name}. 18 </div> 19 <input onChange={(e) => exampleManager.nameHandler.updateName(e.target.value)} /> 20 </div> 21 ) 22}
In context:
1const initialState: ExampleState = { 2 name: '', 3 email: '', 4 nameErrorMessage: '' 5} 6 7interface IExampleContext { 8 exampleState: ExampleState 9 exampleManager?: ExampleManager 10} 11 12export const ExampleContext = createContext<IExampleContext>({ exampleState: initialState }); 13 14const ExampleProvider: React.FC = ({ children }) => { 15 const [exampleState, exampleManager, props] = useOOState(ExampleStateManager, initialState, { userId: '1' }) 16 17 return <ExampleContext.Provider value={{ exampleState, exampleManager }}>{children}</ExampleContext.Provider>; 18}; 19 20export default ExampleProvider;
No vulnerabilities found.
No security vulnerabilities found.