initial_state(
logging_in: false,
current_user: nil,
error: nil,
)
selectors do
CurrentUser = selector do |state|
state[:current_user]
end
LoginState = selector do |state|
state.slice(:logging_in, :error)
end
end
actions do
LogIn = async(:log_in) do |store, username:, password:|
sleep 1
if username == 'foo' && password == 'bar'
{ username: 'foo' }
else
raise InvalidCredentials
end
end
LogOut = action(:log_out)
end
reducer(LogOut) do |state|
state[:current_user] = nil
state[:error] = nil
state[:logging_in] = false
end
reducer(LogIn.pending) do |state|
state[:error] = nil
state[:logging_in] = true
end
reducer(LogIn.fulfilled) do |state, payload|
state[:logging_in] = false
state[:current_user] = payload[:user]
end
The actions will be available in components under Actions::Auth::, like Actions::Auth::LogIn.
The selectors will be available in components under Selectors::Auth::, like Actions::Auth::CurrentUser.
components/CurrentUser.rb
select(
current_user: Selectors::Auth::CurrentUser,
log_in_state: Selectors::Auth::
)
render do
if user = selected[:current_user]
return h.p("Logged in as #{user.name}")
end
h.p "Not logged in"
end
You should also be able to call dispatch anywhere in a component (except in render)...
handler(:log_in) do |form|
username, password = form["fields"].fetch_values("useername", "password")
dispatch(Actions::Auth::LogIn, username:, password:)
end
The idea with selectors is that sometime in the future, it would be possible to update each selector once every time the state updates, and keep track of which components are subscribed to each selector, and only rerender the components that have changed.
This also has to work with the module system, so whenever a store is updated, components should be updated too
stores/Auth.rb
The actions will be available in components under
Actions::Auth::
, likeActions::Auth::LogIn
.The selectors will be available in components under
Selectors::Auth::
, likeActions::Auth::CurrentUser
.components/CurrentUser.rb
You should also be able to call
dispatch
anywhere in a component (except inrender
)...The idea with selectors is that sometime in the future, it would be possible to update each selector once every time the state updates, and keep track of which components are subscribed to each selector, and only rerender the components that have changed.
This also has to work with the module system, so whenever a store is updated, components should be updated too