native-state-react
v3.1.3
Published
Very lightweight and efficient implementation for react global state, just using react hooks. Magic !
Downloads
978
Maintainers
Readme
Features
- Efficient Rendering: Components re-render only when the selected state slice changes.
- No External Dependencies: Uses only React's built-in hooks.
- Lightweight: Total of 115 lines code (entire library).
- Simple API: Use global state like
useStatein React. Neither reducers, actions, or boilerplate code. - Drop-in Replacement: Perfect alternative to Redux and MobX.
Quick Start
Wrap your app with the
<Root>component at the top level, optionally providing the initial state.Use
useNativeStateoruseNativeSelectorin your components to read and update global state.
If you are using version 2.0.x or lower See documentation below
Basic Example
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Root } from 'native-state-react';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<Root />
<App />
</React.StrictMode>
);[!NOTE] Wrap your
<App />inside<Root>(or render<Root />as a top-level sibling component) to initialize your global state. Then, in your component:
import { useNativeState } from 'native-state-react';
function App() {
const [name, setName] = useNativeState('s.name');
const updateName = () => {
setName("George");
};
return (
<div>
<p>Name: {name}</p>
<button onClick={updateName}>Update Name</button>
</div>
);
}See running Demo Here
API
<Root>
The root component that initializes the global state store.
initial: (optional) Object - The initial state. Defaults to an empty object{}.children: (optional) React Nodes - Children to render inside<Root>.
useNativeState(pathString, initialVal)
Hook to read and write a specific slice of the global state using string path notation.
pathString: String - The path to select in the global state, starting with'state'or's'(e.g.'s.name','state.school.class','s.todos[0].title','state.school.class.student[21]').initialVal: (optional) Any - The value to initialize in thepathString. Note that ifpathStringis already initialized or has value set, it will NOT be updated/initilized again, you may cal set method to update the value.
Returns: [value, setValue]
value: The current value at the specified path.setValue: Function to update the value of this specific path.
[!WARNING] if
pathStringiss.todos[0].title,s.todos[0]must exist in the global state so that it can retrieve/settitle
useNativeSelector(selectorFunction)
A highly optimized read-only hook that subscribes to state slices. Components using this hook will re-render only when the selected slice changes. Internally utilizes React's modern useSyncExternalStore for tear-free rendering.
selectorFunction: Function - A function that accepts the state and returns the selected slice (e.g.s => s.name).
Returns: value
value: The read-only value of the selected state slice.
Advanced Example
At App level initialization
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Root } from 'native-state-react';
const initialState = {
name: "Mary",
school: { class: "V" }
};
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<Root initial={initialState}>
<App />
</Root>
</React.StrictMode>
);
Using both useNativeState for writing state slices and useNativeSelector for highly optimized read-only selections:
import { useNativeState, useNativeSelector } from 'native-state-react';
import { useEffect } from 'react';
function ClassComponent() {
// Syncs and updates the specific path 's.school' with an optional on-mount default
const [school, setSchool] = useNativeState('s.school', { class: "V" });
useEffect(() => {
const timer = setTimeout(() => {
setSchool({ class: "1A" });
}, 3000);
return () => clearTimeout(timer);
}, [setSchool]);
// Read-only selector; component only re-renders if 'name' changes
const name = useNativeSelector(s => s.name);
return (
<div>
<p>Student Name: {name}</p>
<p>Class: {school?.class}</p>
</div>
);
}[!IMPORTANT] Thanks for reading this much. I am glad that you are using this. If you like this, please do ⭐ this repository.
Examples
See the example folder for a complete React project implementation demonstrating live updates, time stamps, and cross-component syncing.
Documentation for versions <= 2.0.x
If you are using legacy versions of native-state-react (versions 2.0.x or below), please refer to the documentation below:
Quick Start
Wrap your app with the
<Root>component at the top level, providing the initial state.Use
useSelectorin components to access and update global state.
Basic Example
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Root } from 'native-state-react';
const initialState = {
name: "Mary",
school: { class: "V" }
};
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<Root initial={initialState} />
<App />
</React.StrictMode>
);In your component:
import { useSelector } from 'native-state-react';
function App() {
const [name, setState] = useSelector(s => s.name);
const updateName = () => {
setState({ name: "George" });
};
return (
<div>
<p>Name: {name}</p>
<button onClick={updateName}>Update Name</button>
</div>
);
}API
<Root>
The root component that provides the global state context.
initial: (optional) Object - The initial state. Defaults to an empty object{}.
useSelector(selector)
Hook to select a slice of the global state.
selector: Function - A function that takes the state and returns the desired slice.
Returns: [value, setState]
value: The current value of the selected slice.undefinedif the slice doesn't exist.setState: Function to update the global state by merging the provided object.
Note: setState merges the provided object into the global state. It can update any part of the state, not just the selected slice.
Advanced Example
import { useSelector } from 'native-state-react';
import { useEffect } from 'react';
function ClassComponent() {
const [schoolClass, setState] = useSelector(s => s.school?.class);
useEffect(() => {
const timer = setTimeout(() => {
setState({ school: { class: "1A" } });
}, 3000);
return () => clearTimeout(timer);
}, []);
return <div>Class: {schoolClass}</div>;
}This updates the school.class after 3 seconds, and the component will re-render.
BENCHMARK TEST RUN
Code used to run benchmark will be added to benchmarks folder soon.
