A short exploration of a method for building websites that work without JS, while still enjoying the convenience of modern frontend and backend technologies - with live coding!
Using Next.JS and Redux for Epic Noscript Web Apps
AI Generated Video Summary
1. Introduction to No-Script Web Apps
So instead of having just a simple click handler on a button, instead we do something like this. We wrap it in a form and set the action to just an empty string so that when you submit this form, it's going to be sent to the same route that we're already at, which means a view route. And we make the assumption that the only reason why anyone would ever do a post request to a view routes is because they are submitting this kind of form that wraps an action that they want to perform. And inside it, we embed the current state or the client state, the app state and also the kind of action that we want to be dispatched. And we will replace our button type button with a submit button. And you can also omit the type attribute here.
Then in our app.js, if you're using Next.js that is, we have this get initial props, and we check for if this is a post request, well, then we want to read the body and the body will look something like this. It'll have an action type, for example, and the state. And we pass that along to a helper function. Now we'll parse the payload. Using the callback that we supplied, getReduxStore, it'll take the parsed state in the payload and create a new ReduxStore with that. And also dispatch the action in the payload to that ReduxStore and return the updated ReduxStore and the updated state. Then we can assign that to our preloaded state and re-render our application with that state.
3. React Helpers and Handling Async Actions
To help us with this, I've created some React helpers that I've added in an npm package. The most important component is the form component that embeds the state. It selects the state from the Redux and embeds it into the form. It also handles the submit by preventing defaulting on the client side and parsing the payload. We're serializing both the action and the payload into the form. We also have a button that wraps in the form component and passes along the necessary props. For async actions in a no-script scenario, we need to call and await the action creator instead of simply telling the server to dispatch an action.
To help us with this, I've created some React helpers that I've added in an npm package. And the most important component is the form component that embeds the state. It selects the state from the Redux and embeds it into the form. And also handles the submit. Which means preventing defaulting on the client side and parsing the payload. Because instead of just passing objects, we're actually typing out all the... We're serializing both the action and the payload into the form. So it parses the form payload and also dispatches any action contained within.
We also have a button, which is a simple helper that just takes a button and wraps it in the form component. And also passes along the necessary props. And you can find this on at witchy-gift.com. But I hear you. First of all, you were promising epic webapps. And second of all, how would you do it with async actions? Well, I got a solution for that as well. Who'da thunk?
And when there's an action creator, the server will notice that and just await the dispatch of the action creator.
5. Adding Form and Surprise
We added the action to submit and used the button component instead of a normal button. For this part, we changed the wrapper to be the form component. When pressing the first button, it will decrement by the amount entered in the input. Pressing the second button will increment by the entered amount. We also added a surprise by generating a random number between -50 and 50 using the increment by amount action.
It works as you would expect. Okay, so we got that working and it was just a tiny change. This is less code than before. We just added the action that we wanted to submit and used the button component instead of a normal button.
Great. But the thing is that if you decide to refresh the page, you'll see that we get the exact same number every time. And that's because we're resending the exact same state and we also hardcoded the random numbers. And that is also being resend when we resubmit the form. That's not very surprising, is it?