Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/cellog/tiny

Created with CodeSandbox
https://github.com/cellog/tiny

Last synced: 4 days ago
JSON representation

Created with CodeSandbox

Awesome Lists containing this project

README

        

# Tiny
### A tiny react-based state management library

Refactor-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.