Skip to content

Instantly share code, notes, and snippets.

@DmytroVasin
Created February 4, 2018 12:14
Show Gist options
  • Save DmytroVasin/01c1e10da3cc2ab7de546183cf913006 to your computer and use it in GitHub Desktop.
Save DmytroVasin/01c1e10da3cc2ab7de546183cf913006 to your computer and use it in GitHub Desktop.
Ruby implementation of redux store
todos_reducer = -> (state, action) {
state ||= []
case action[:type]
when 'add'
state.push(action[:todo])
when 'remove'
state.remove(action[:todo])
else
state
end
}
counter_reducer = -> (state, action) {
state ||= 0
case action[:type]
when 'increment'
state += 1
when 'decrement'
state -= 1
else
state
end
}
counter_listener = -> () { p 'I am counting numbers' }
class ReduxStore
def self.combine_reducers(reducers)
-> (state, action) {
state ||= {}
reducers.reduce({}) { | next_state, (key, reducer) |
next_state[key] = reducer.call(state[key], action)
next_state
}
}
end
attr_reader :current_state
def initialize(reducer)
@reducer = reducer
@listeners = []
@current_state = nil
dispatch({})
end
def dispatch(action)
@current_state = @reducer.call(@current_state, action)
@listeners.each { |l| l.call }
end
def subscribe(listener)
@listeners.push(listener)
-> { @listeners.delete(listener) }
end
end
root_reducer = ReduxStore.combine_reducers({ counter: counter_reducer, todos: todos_reducer })
# my_counter_store = ReduxStore.new(counter_reducer)
my_counter_store = ReduxStore.new(root_reducer)
my_counter_store.dispatch({ type: 'increment' })
my_counter_store.dispatch({ type: 'add', todo: 'Buy milk' })
my_counter_store.dispatch({ type: 'add', todo: 'Buy milk again' })
my_counter_store.dispatch({ type: 'increment' })
my_counter_store.dispatch({ type: 'increment' })
my_counter_store.dispatch({ type: 'decrement' })
my_counter_store.dispatch({ type: 'decrement' })
my_counter_store.dispatch({ type: 'increment' })
p my_counter_store.current_state
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment