Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cellog/tiny
Created with CodeSandbox
https://github.com/cellog/tiny
Last synced: 4 days ago
JSON representation
Created with CodeSandbox
- Host: GitHub
- URL: https://github.com/cellog/tiny
- Owner: cellog
- Created: 2018-08-31T02:51:21.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2018-09-29T04:17:12.000Z (over 6 years ago)
- Last Synced: 2024-11-09T19:33:14.424Z (2 months ago)
- Language: JavaScript
- Homepage: https://codesandbox.io/s/github/cellog/tiny
- Size: 574 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Tiny
### A tiny react-based state management libraryRefactor-focused, test-focused state management, with full support for suspense.
```js
import Provider, { async } from "./Provider.jsx"
import StateConsumer from "./StateConsumer.jsx"
import ActionConsumer from "./ActionConsumer.jsx"
import React from "react"
import { render } from "react-dom"
const $$observable = Symbol.for("observable")function inc(state) {
return { counter: state.counter + 1 }
}function dec(state) {
return { counter: state.counter - 1 }
}const asyncTimer = {
make: () => ({
[$$observable]: () => this,
subscribe(observer) {
const timeout = setInterval(() => observer.next(), 1000)
return { unsubscribe: () => clearInterval(timeout) }
}
}),
init: (observable, actions, action) => ({
next: actions.actions[action]
}),
start: (observable, observer) => observable.subscribe(observer)
}const asyncDelay = {
make: ms =>
new Promise(resolve => {
setTimeout(resolve, ms)
}),
init: (promise, actions, ms, action) => actions.actions[action],
start: (promise, action) => promise.then(action)
}const Button = ({ action, children, disabled = false }) => (
{
return (
{children}
)
}}
/>
)const AsyncButton = ({
action,
handle = () => null,
args = [],
children,
disabled = false
}) => (
{
return (
handle(generators[action](...args))}
disabled={disabled}
>
{children}
)
}}
/>
)const Counter = () => state.counter} />
class App extends React.Component {
state = { timing: false, delay: false }render() {
if (this.state.error) throw this.state.error
return (
+
-
{this.state.timing ? (
{
this.state.timing.unsubscribe()
this.setState({ timing: false })
}}
>
stop counting
) : (
this.setState({ timing })}
args={["inc"]}
>
count
this.setState({ timing })}
args={["dec"]}
>
count down
)}
{
this.setState({ delay: true })
delay
.then(() => this.setState({ delay: false }))
.catch(error => this.setState({ error, delay: false }))
}}
disabled={this.state.delay}
>
delay
{
this.setState({ delay: true })
delay
.then(() => this.setState({ delay: false }))
.catch(error => this.setState({ error, delay: false }))
}}
disabled={this.state.delay}
>
delay down
)
}
}const div = document.body.appendChild(document.createElement("div"))
render(, div)
```## Key features
### build local first, then lift state
Build your state locally, then if another component needs access to the state, lift it up:
```js
class MyClass extends React.Component {
constructor(props) {
super(props)
this.state = {
something: 1
}
this.changeSomething = () => this.SetState({ something: 2 })
}componentDidUpdate(nextProps) {
if (lastProps.blah !== this.props.blah) {
api.load(this.props.blah)
.then(thing =>
this.setState(state => {
return { something: state.something + thing}
}))
}
}render() {
return (
{this.state.something}
+
)
}
}
```lift:
```js
import { lift, liftSetState } from 'tiny'class MyClass extends React.Component {
constructor(props) {
super(props)
this.state = this.props.initState('myclass', {
something: 1
})
this.liftedSetState = liftSetState(this, 'myclass')
this.changeSomething = () => this.liftedSetState({ something: 2 })
}componentDidMount() {
this.props.liftActions('myclass', { changeSomething: this.changeSomething })
}componentDidUpdate(nextProps) {
if (lastProps.blah !== this.props.blah) {
api.load(this.props.blah)
.then(thing =>
this.liftedSetState(state => {
return { something: state.something + thing}
}))
}
}render() {
return (
{this.state.something}
+
)
}
}export default lift(MyClass)
```Now, other components can access your component's state and actions:
```js
const Fancy = ({ state, actions: { actions } }) => (
{state.myclass.something}
change it!
)const ConnectFancy = (
)
```### Build asynchronous action generators that are pure and testable
### Build for correctness, and add speed easily later
Using `SubProvider` and observed bits mappers, speed can easily be applied in components
that render too often. No need for confusing solutions like reselect.