Last active
November 2, 2024 21:10
-
-
Save eadz/31c87375722397be861a0dbcf7fb7408 to your computer and use it in GitHub Desktop.
Redux in Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Redux in Ruby | |
class Store | |
attr_reader :state | |
def initialize(initial_state, *reducers) | |
@reducers = reducers | |
@state = initial_state || {} | |
end | |
def dispatch(action) | |
@state = @reducers.reduce(state.dup) do |s, reducer| | |
reducer.call(s, action) | |
end | |
end | |
end | |
# Reducers | |
totals_reducer = ->(state, action) do | |
case action[:type] | |
when 'ADD_ITEM' then state[:total] += 1 | |
when 'REMOVE_ITEM' then state[:total] -= 1 | |
end | |
state | |
end | |
items_reducer = -> (state, action) do | |
case action[:type] | |
when 'ADD_ITEM' then state[:items] << action[:item] | |
when 'REMOVE_ITEM' then state[:items] = state[:items] - [action[:item]] | |
end | |
state | |
end | |
# DEMO | |
@store = Store.new({ total: 0, items: [] }, items_reducer, totals_reducer) | |
@store.dispatch type: 'ADD_ITEM', item: 'APPLES' | |
@store.dispatch type: 'ADD_ITEM', item: 'BANANAS' | |
@store.dispatch type: 'REMOVE_ITEM', item: 'APPLES' | |
@store.dispatch type: 'ADD_ITEM', item: 'FEIJOAS' | |
puts @store.state # => {total: 2, items: ["BANANAS", "FEIJOAS"]} |
π
Oddly enough I just implemented the same thing for a bit of fun and our implementations are extremely similar. A good sign for me, at least :-) One thing that's easy enough to add is a subscribe
method and push a passed block onto an array of procs that can be called with the new state at the end of dispatch
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Super cool, @eadz! π
Line 12 might be a good place to use
Enumerable#reduce
(inject
alias) as its name makes more sense in that context? π