🇫🇮
Renderer = View
(State)
Renderer = View
(State)
Behavior?
Renderer = View
(State)
before fetching
after fetching
isFetching: true
Jeremy Fairbank elm-conf 2017
type FetchingState =
| BeforeFetching
| Fetching
| FetchedValidData
| FetchedCorruptedData
| FetchedError
First class edge cases
type LayoutProps = {
main?: boolean;
header?: boolean;
right?: boolean;
}
type LayoutProps = {
main?: boolean;
header?: boolean;
right?: boolean;
}
<Layout main />
<Layout header />
<Layout right />
8
3
type LayoutType =
| Main
| Header
| Right
<MainLayout />
<HeaderLayout />
<RightLayout />
type LayoutProps = {
main?: boolean;
header?: boolean;
right?: boolean;
}
const layoutProps = {
isMain: false,
isHeader: false,
isRight: false
}
Mutually Exclusive
Uncertainty
Limited values
Complexity growth
Priority will matter
isLoading: boolean
isMain: true;
isHeader: true;
const ArticleList = ({list}) => {
return (
{list.length === 0 ? <p>Empty list</p> : null}
)
}
const Article = ({ article }) => (
<div>
{article.pictures.length ? (
<>
<Picture src={article.pictures[0].url} />
<PictureCaption>{article.pictures[0].caption}</PictureCaption>
</>
) : null}
</div>
);
switch(event.type) {
case "SET_CHECKING":
return {
...state,
checking: true,
error: undefined
}
case "CHECK_SUCCESS":
return {
...state,
checking: false,
status: event.payload
}
case "CHECK_FAILURE":
return {
...state,
checking: false,
error: event.payload
}
default:
return state;
}
{
status: undefined,
checking: false,
error: undefined
}
type HealthCheckState
=
| Idle
| Checking
| Success status
| Failure error
{
status: undefined,
checking: false,
error: undefined
}
I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea.
The big idea is "messaging"
document.getElementById("button")
.addEventListener("click", e => {
// Run side effects
})
dispatch({ type: "authorize_session" });
function authorizeHandler(state) {
if (state.session.isLoggedIn) {
dispatch({ type: "session_authorized" });
} else {
if (isSessionValidForRefreshing(state.session.lastLoggedIn))
{
dispatch({ type: "retry_session" });
} else {
if (state.session !== undefined) {
dispatch({ type: "session_logout" });
}
}
}
}
login()
logout()
checkout()
addToCart()
LoginView
LogoutView
CheckoutView
CartView
FSM(State + Event) => NextState + SideEffects
Purity vs Idempotence
Reducing logic
Finite state machines
Guarding vs Not Allowing
Event->Action
Event+State->Action
Travel To Past
vs
Travel to Past & Future
Idiomatic reducing logic
Idempotence
MAKE IMPOSSIBLE STATES IMPOSSIBLE
Making Impossible States Impossible by Richard Feldman
MAKE IRRELEVANT DATA UNAVAILABLE
DO NOT TEST SOMETHING THAT IS NOT SUPPOSED TO HAPPEN
TESTING IS GOOD.
IMPOSSIBLE IS JUST BETTER.
Making Impossible States Impossible by Richard Feldman
Constructing the user interface with statecharts / Ian Harrocks