Atila
I'm on a mission to make code simple. When not recording screencasts or courses, you may find me either writing and talking about jamstack, performance, or developer tooling.
2022
(he/him)
{...design}
{...design}
✨
Server
renders
static
data source
Browser
renders
all
all
click
mutation event
mutation request
response
update content
woohoo!
click
mutation event
mutation request
response
update content
woohoo!
Don’t
go
chasing
waterfalls
💭 this song is from 1995
click
mutation event
mutation request
response
update content
woohoo!
✅
click
mutation event
mutation request
💥
update content
woohoo!
update content
Pardon. retry?
if your App/API fails often, you probably have a bug
not a silver bullet
🐛
🔫
when the response is not critical to the user experience
when you trust the availability of the resource
🐶
☀️
when a page loads
`GET`
requests
⬇️
⚙️
when a data mutates
`POST`
requests
⬆️
⚙️
`PUT`
`DELETE`
`PATCH`
`useLoaderData()`
`useActionData()`
GET form submission
POST / PUT / PATCH / DELETE form submission
from remix
not react
⚠
navigation
idle
idle
loading
idle
idle
submitting
idle
idle
submitting
loading
1️⃣
2️⃣
3️⃣
const PageComponent = () => {
const loaderData = useLoaderData()
const transition = useTransition()
return (
<h1>
{transition.state === 'submitting'
? `Submitted ${transition.submission.formData.get('username')}`
: `Already have ${loaderdata?.username || 'nothing'}`
}
</h1>
)
}
<Form>
<fetcher.Form>
vs
<form>
vs
🪝
This hook lets you plug your UI into your actions and loaders without navigating
-- from Remix docs
POST
PUT
DELETE
PATCH
Action
Function
Loader
Function
const PageComponent = () => {
const { data, submission, state } = useFetcher()
const loaderdata = useLoaderData()
const formData = submission.formData
const food = fetcher.data
? `${data.cuisine} ${data.dish}`
: loaderdata.food
return (
<h1>
{state === 'submitting'
? `We are eating ${formData.get('dish')} for dinner`
: `We are eating ${food || 'nothing'} for dinner`
}
</h1>
}
Tanstack Query
featuring
getServerSideProps
QueryClient
initialData
Hydrate page with data
cache query
mutate
✅
❌
Re-Render page w/ new data
update cache
Re-Render page w/ old data
pull from cache
warn user
function App({ Component, pageProps }) {
const [queryClient] = useState(
() => new QueryClient()
)
return (
<QueryClientProvider client={queryClient}>
{/*... app stuff goes here */}
</QueryClientProvider>
)
}
function Page({ pageData }) {
const { data } = useQuery(
['data'],
() => {
return getData(user)
},
{
initialData: pageData,
}
)
return <Component />
}
const getServerSideProps = async ({
req,
res
}) => {
const user = await getUser()
return {
props: {
pageData: await fetchData(user)
},
}
}
const useAddTodo = (user) => {
const queryClient = useQueryClient()
return useMutation(
(newTodo: TodoProps) => addTodo(newTodo, userEmail), {
onMutate: async (newTodo) => {
await queryClient.cancelQueries(['todos'])
const previousTodos = queryClient.getQueryData(['todos'])
queryClient.setQueryData(['todos'], (oldTodos => [
newTodo,
...oldTodos,
])
return { previousTodos }
},
onError: (err, _newTodo, context) => {
queryClient.setQueryData(['todos'], context.previousTodos)
},
onSettled: () => {
queryClient.invalidateQueries(['todos'])
},
})
)
}
By Atila
Remix is a framework revitalises web development by putting progressive enhancement in the front seat. It creates solutions that approximates developers to the platform. It uses Developer Experience as means to enforce web best practices and with that brought the term Optimistic UI back to our daily lives. Let's have a look at what features the Remix offers out-of-the-box to get developers creating high-quality web apps easily and deploying them anywhere that can run JavaScript.
I'm on a mission to make code simple. When not recording screencasts or courses, you may find me either writing and talking about jamstack, performance, or developer tooling.