So I just started some background processing. Asked myself, what's available when JavaScript is disabled? It's just HTML and CSS. Okay. How can I convert this already existing application to one that works without JavaScript? No idea. And how can I do it in a way that's maintainable? Because I didn't want to have two separate codebases that would need to be maintained.
Well, fast forward to 2020, and I think I wake up one day, and my mind has put some pieces together. I realized that one of the tenets of Redux, which is thou shalt only put serializable values in state or actions, goes very well with, or actually aligns perfectly with a certain type of payload that's also serializable. Well, talking about forms, the solution was there all along. Instead of having standalone buttons, I could simply wrap them in a form and prevent default on the submit so that if there was JavaScript enabled, the event would be prevented. And if there wasn't, well, it just hit the server and we can have our server dispatch whatever action that we want to perform.
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.
So when JavaScript is enabled, user clicks the button, the event is prevented and the action is dispatched. State is updated and the React application re-renders client side. And it's quite similar when JavaScript is disabled, except that we can't prevent default. So the request will hit the server and our server will parse the payload and dispatch the action, get the updated state and re-render the React application server-side. And in both scenarios, the end result is the exact same. The state you end up with is exactly the same. And also, the HTML is exactly the same.
Comments