Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kenmueller/sobs
React observables
https://github.com/kenmueller/sobs
Last synced: about 2 months ago
JSON representation
React observables
- Host: GitHub
- URL: https://github.com/kenmueller/sobs
- Owner: kenmueller
- Created: 2020-04-02T20:15:30.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2022-03-26T10:52:39.000Z (almost 3 years ago)
- Last Synced: 2024-05-28T15:30:04.103Z (7 months ago)
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/sobs
- Size: 56.6 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# sobs
> React state management using observables. Modeled after SwiftUI. No boilerplate.
## Table of contents
- [**Install**](#install)
- [**Introduction: Observable Objects and Published**](#introduction)
- [**Environments & Environment Objects**](#environments)## Install
**IMPORTANT: You must be using TypeScript**
`npx create-react-app {app_name} --template typescript`
```bash
npm i sobs
```## Documentation
### Introduction: Observable Objects and Published
### **IMPORTANT: Before you start...**
In your `tsconfig.json`, set `experimentalDecorators` to `true`:
```json
{
"compilerOptions": {
"experimentalDecorators": true
}
}
```### 1. Create an `@ObservableObject`
```tsx
import { ObservableObject } from 'sobs'@ObservableObject
class User {
// Go to the next step
}
```### 2. Create fields
Normal fields don't cause component updates when they change.
You must mark a field with `@Published` for components to respond to its changes.
```tsx
import { ObservableObject, Published } from 'sobs'@ObservableObject
class User {
id: string // If this changes, components won't respond
@Published name: string // If this changes, components will update
constructor(id: string, name: string) {
this.id = id
this.name = name
}
// If you are modifying an @Published variable, you must use a regular function expression.
// Arrow functions are not allowed.
resetToDefaultName() {
this.name = '...'
}
}
```### 3. Create a store
```tsx
import { ObservableObject, Published } from 'sobs'@ObservableObject
class User {
id: string
@Published name: string
constructor(id: string, name: string) {
this.id = id
this.name = name
}
resetToDefaultName() {
this.name = '...'
}
}@ObservableObject
class Store {
@Published users: User[] = []
addUser(user: User) {
// Using .push(...) on an array doesn't trigger component updates.
// You must reassign the array in order to trigger an update.
this.users = [...this.users, user]
}
deleteUser(id: string) {
this.users = this.users.filter(user => user.id !== id)
}
}
```### 4. Create components
```tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { ObservableObject, Published, observe, newId } from 'sobs'@ObservableObject
class User {
id: string
@Published name: string
constructor(id: string, name: string) {
this.id = id
this.name = name
}
resetToDefaultName() {
this.name = '...'
}
}@ObservableObject
class Store {
@Published users: User[] = []
addUser(name: string) {
this.users = [
...this.users,
new User(newId(), name)
]
}
deleteUser(id: string) {
this.users = this.users.filter(user => user.id !== id)
}
}const store = new Store()
const App = () => {
// Respond to updates in the store.
// This will only respond to field reassignments; it's shallow.
// Updating a User object in the users array won't cause an update in this component.
observe(store)
return (
store.addUser(prompt('Name')!)}>
Add user
{store.users.map(user => (
))}
)
}const UserRow = ({ user }: { user: User }) => {
// This will respond to updates on the user object.
observe(user)
return (
{user.name}
{/* This component will respond */}
Reset to default name
store.deleteUser(user.id)}> {/* The App component is observing the store object, so this will cause an update */}
Delete
)
}ReactDOM.render(, document.getElementById('root'))
```### Environments & Environment Objects
Documentation coming soon