0.1.10 • Published 7 years ago

tiny-state-manager v0.1.10

Weekly downloads
3
License
MIT
Repository
github
Last release
7 years ago

tiny-state-manager

Very easy to understand and pretty simple. In the past I found that redux was a lot of boiler plate for a lot of the simple use cases I had. Concentrating all state mutating actions in one place made sense to me. When I use this I will typically attach a listener to handle stuff like API requests and what not.

You can find a simple 'counter' example in the aptly named 'example' folder

The whole thing is tiny

import EventEmitter from 'events'

const appState = seedState => {
  const emitter = new EventEmitter()
  let state = seedState || {}
 
  emitter.on('set', function(payload) {
      state = payload
      this.callback(state)
  })
  
  emitter.on('reset', function() {
      seedState && (state = seedState)
      this.callback(state)
  })
  
  emitter.on('update', function(payload) {
      state = {...state, ...payload}
      this.callback(state)
  })
  
  return {
    emitter,
    state
  }
}

export default appState

I typically use this in a top-level 'container' component (most of my react projects are small SPA's)

//...other imports...
import React, {Component} from 'react'
import MyUserComponent from './MyUserComponent'
import appState from 'tiny-state-manager'

// setup initial app state as object
const initAppState = {
  loading: false,
  userObject: {},
  moreStuff: []
}

// call appState with initial state object to get state manager
const stateManager = appState(initAppState)

class AppContainer extends Component {
  constructor(props) {
    super(props)
    // set the stateManager's emitter callback so container state gets updates
    stateManager.emitter.callback = x => this.setState(x)
    // load initial container state from the stateManager
    this.state = stateManager.state
  }
  
  render() {
    const {emitter} = stateManager
    const {userObject} = this.state
    // pass the emitter down to any component that needs
    // to communicate a state change request via
    // props.emitter.emit('update', {...newState})
    return (
      <div>
          <MyUserComponent {emitter} {userObject}/> 
      </div>
    )
  }
}

Now your more 'presentation' oriented components have the state they need and a way to request state mutations

import React from 'react'

export default = props =>
  <div>
    <div>
      Howdy, {props.userObject.name ? props.userObject.name : 'stranger'}!
    </div>
    <div>
      Change Name: 
        <input type="text" onChange={x => props.emitter.emit('update', {userObject: {...props.userObject, name: x.target.value})}/>
    </div>
  </div>

Adding API calls may be like this (but with error handling...)

stateManager.emitter.on('action', function(payload) {
    switch(payload.type) {
        case 'login':
            fetch('http://our.api.io/users', {method: 'POST', body: payload.data})
            .then(x => x.json())
            .then(x => this.emit('update', {userData: {x}}))
        break
    }
})

and now you can just emit this from wherever you have a handle on the emitter

import React from 'react'

export default = props =>
  <div>
    <div>
      Howdy, {props.userObject.name ? props.userObject.name : 'stranger'}!
    </div>
    <div>
      Change Name: 
        <input type="text" onChange={x => props.emitter.emit('update', {userObject: {...props.userObject, name: x})}/>
    </div>
    <button type="button" onClick={() => props.emitter.emit('action', {type: 'login', data: {...props.userObject}})}
  </div>

A function called getState() was added to the emitter object to allow you to get a copy of the current state from a stateless component that may not have all context cleanly passed via props (like perhaps a form). Use it like:

// ...stuff...
<button onClick={() => {
  let {count} = props.emitter.getState()
  props.emitter.emit('update', {count: ++count})
}}>+1</button>

Nothing fancy, no middlewares, etc.

0.1.10

7 years ago

0.1.9

7 years ago

0.1.8

7 years ago

0.1.7

7 years ago

0.1.6

7 years ago

0.1.5

7 years ago

0.1.4

7 years ago

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago