Senko - easy global state in react
Raghav Misra
Posted on April 25, 2021
Straightforward global state in React.
This project is a work-in-progress, so feel free to contribute. :D
Feedback much, much appreciated!
Why Senko?
When writing React apps, global state management becomes a larger concern than it should be. Enter Senko, an easy state management solution with a lot of power.
Let's look at a simple example:
import React from "react";
import senko from "senko";
const useStore = senko({ count: 0 });
function Counter() {
const store = useStore();
return <>
<code>{store.count}</code>
<button onClick={() => store.count++}>up</button>
<button onClick={() => store.count--}>down</button>
</>;
}
The useStore
hook that is returned from the senko(...)
call can be called from any component, and they will all refer to the same state.
Features:
- First-class Typescript support
(like really first class). - Multiple
senko
calls can be used to make isolated stores that can then be used in any component. - Really straightforward, no top-level provider wrappers, etc.
Check it out!
Let's build an example:
Scaffold an app with CRA
npx create-react-app senko-test --template=typescript
(feel free to follow along with JS instead)
Restructure files & folders
- Delete everything in
/src
- Create the following files in
/src
:index.tsx
store.ts
yarn add senko
No senko app is complete without senko!
Write the store
Inside store.ts
, throw the following.
I've added comments to walk you through it.
// No senko app is complete without senko!
import senko from "senko";
// We're gonna have a signup form:
// Pass in the initial state to the senko function:
export const useStore = senko({
username: "",
email: "",
password: ""
});
// Oh also you can use a default export instead,
// I'm just not a big fan xD.
Write the frontend
Okay, now that the store is done, we can write the actual React code.
Here's a template so you don't need to write the small stuff:
import React from "react";
import ReactDOM from "react-dom";
import { useStore } from "./store";
function Form() {
}
ReactDOM.render(<Form />, document.querySelector("#root"));
Now, we have the basic stuff in place, let's dive into writing the Form
component.
function Form() {
return (
<form>
<label>Username:</label>
<input
type="text"
placeholder="CoolGuy1234"
/>
<label>Email:</label>
<input
type="email"
placeholder="coolguy1234@gmail.io"
/>
<label>Password:</label>
<input
type="password"
placeholder="Shhhhhhhhh!"
/>
<button type="submit">Signup!</button>
</form>
);
}
There's our form structure (not a great-looking one, but it's there).
Two-way binding
Now let's look at binding these inputs to the store.
function Form() {
const store = useStore(); // we imported this before
/* omitted for brevity */
}
Usually, a two-way binding would like this:
<input
value={store.username}
onInput={e => store.username = e.target.value}
/>
However, with a Senko store, you can use our two-way binding helper:
<input {...store.model.username()} />
Basically use store.model.thePropYouWantToBindTo
(in our case: username
, email
, and password
).
These bindings in our Form
component would look like:
function Form() {
const store = useStore();
return (
<form>
<label>Username:</label>
<input
type="text"
placeholder="CoolGuy1234"
{...store.model.username()}
/>
<label>Email:</label>
<input
type="email"
placeholder="coolguy1234@gmail.io"
{...store.model.email()}
/>
<label>Password:</label>
<input
type="password"
placeholder="Shhhhhhhhh!"
{...store.model.password()}
/>
<button type="submit">Signup!</button>
</form>
);
}
Finishing up
How do we know this two-way binding actually works?
Let's add a submit
event to our form and prove it!
function Form() {
const store = useStore();
const onLogin: React.FormEventHandler = (e) => {
e.preventDefault();
console.log(
"You signed up with the username:",
store.username,
"\nThe email:",
store.email,
"\nAnd your password was supposed to be secret but we don't care:",
store.password
);
};
return (
<form onSubmit={onLogin}>
{/* omitted for brevity */}
</form>
);
}
Try it out
Keep adding different values to the inputs and hitting submit!
You should see updated values everytime.
Farewell!
Thanks for reading this far! :D
Hope you enjoyed this post, a reaction or feedback would be much appreciated.
Posted on April 25, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.