Transcript
00:00:00First we had JSX, then we had TSX, but we've been stuck with these for years now.
00:00:04Can't they be improved? Well, maybe by TSRX.
00:00:08It's kind of the same, but it's different.
00:00:10We don't have a function, we have a component, we have strings for our text,
00:00:14there's a normal if statement in here, and there's also no return statement.
00:00:17So what is this, why, and should you use it? Let's find out.
00:00:21[Music]
00:00:26Now there might be a few of you that have actually seen code like this before,
00:00:29and that's because it's actually brought to you by the creator of Ripple.
00:00:31This is a new front-end framework that Rich had covered on this channel six months ago,
00:00:35so subscribe to keep up to date with these things.
00:00:38What they've done is they've extracted the syntax used in Ripple,
00:00:41and they made it work with React, Preact, Solid, Vue, and Ripple of course,
00:00:45and a lot of people were pretty hyped for this.
00:00:47Now TSRX describes itself as a way to write UI components that stay readable and co-located,
00:00:52so structure, styling, and control flow live together,
00:00:55and the result stays fully backward compatible with TypeScript.
00:00:58But unless you've used Ripple before, you're probably still a little confused by what that means,
00:01:01so let's go through its features.
00:01:03To start you use this with TSRX files, which does mean that we need a compiler step,
00:01:07but that is super easy to set up with a VIT plugin,
00:01:10and there's also other options for other frameworks and runtimes as well.
00:01:13As for the actual components, instead of writing function here, we write component,
00:01:17and this is mostly just a keyword for the compiler itself,
00:01:20but it also makes it clear that this is going to contain some rendering logic.
00:01:24I'd maybe consider it a small quality of life improvement.
00:01:27One thing to notice though is that we have no return statement here,
00:01:30and that's because TSRX uses statement-based JSX,
00:01:33so you don't need to return a component tree,
00:01:35you just write your markup wherever you want it to render.
00:01:37This means that we can actually drop in another paragraph tag above this card at the top of the component,
00:01:42and it's going to render in where it's written.
00:01:44You can still use a return in a component, but it has to be a bare one,
00:01:47and it's only used for early returning, so UI and logic after this is skipped.
00:01:51It's helped me to think of TSRX components as very linear,
00:01:54so the order that we write the source in is the order of rendering,
00:01:57simply reading from top to bottom,
00:01:59but I can also see that this might make it harder to quickly see what a component is rendering,
00:02:03whereas in something like React, we would just jump straight for the return.
00:02:06Another benefit of statement-based JSX is that we can use a lot more normal JavaScript.
00:02:10For example, conditional rendering is super simple.
00:02:13It is just an if statement with an else-if and else-to if you need them.
00:02:17In the conditions, we simply just need to place our JSX as a statement.
00:02:20This same shape in React often turns into nested ternaries,
00:02:23because in JSX, every branch has to be an expression,
00:02:26so I find that the TSRX version can sometimes read easier,
00:02:29especially when we have a more complex statement,
00:02:31but in the same way, I can also see that this may add more verbosity,
00:02:35especially when you just need a simple condition.
00:02:37It's the same story for switch statements as well.
00:02:39You can just use a normal JavaScript switch with your cases
00:02:41and the JSX you want to render for each one.
00:02:44This is a little more simple than how you would handle this in React,
00:02:47where you need a function to use the same pattern,
00:02:49so TSRX is a little cleaner here,
00:02:51but an area that I personally like TSRX less is in list rendering.
00:02:55Here we ditch .map and instead we use a for-off loop,
00:02:58and TSRX has actually extended this loop so we can get the index out
00:03:01as well as a stable identity with the key.
00:03:03Then when you want to skip an item, you can simply use continue,
00:03:06so again, it's a bit closer to the vanilla JavaScript flow,
00:03:08but as I said, for me, I've gotten very used to using .map, filter, and so on,
00:03:12so I'll probably be sticking to that,
00:03:14and it's also worth noting that you can't use any other loop types
00:03:17like for, for-in, while, and do-while.
00:03:19It is only for-off that this works for.
00:03:21Now continuing the trend of using normal JavaScript,
00:03:23the way that we do error boundaries in TSRX is with a simple try-catch block.
00:03:27Nothing fancy and pretty self-explanatory.
00:03:30We can then also use the same try-catch block if we need async boundaries,
00:03:33we simply just need to add in a pending block
00:03:35and then write your loading component in there.
00:03:38The compiler actually handles taking this code
00:03:40and resolving it to whatever framework you're using,
00:03:42so in React, Preact, and Solid, this actually uses lazy,
00:03:45and in Ripple, it's the Ripple equivalent.
00:03:47Talking of React specifically though,
00:03:48the features that we've looked at so far
00:03:50appear to allow us to break one of React's key rules,
00:03:53the rule of hooks.
00:03:54We can now place them after conditions and early returns,
00:03:57and even inside of loops.
00:03:58They will all work as normal.
00:04:00This lets us better co-locate our code to where it's actually needed,
00:04:03and the final output doesn't even break the rules.
00:04:06The compiler just quietly hoists every hook to the top of the generated function,
00:04:09so React still sees them in a stable order,
00:04:11but you get to write them where they actually belong.
00:04:14Now for me, as someone who's used React for years,
00:04:16this is one of the ones that I struggle to get used to,
00:04:18and it's also a feature where we're making the compiler
00:04:20do a lot more behind-the-scenes magic,
00:04:22specifically around a framework,
00:04:24and I think if I was debugging this,
00:04:26I might get a bit lost as to what code is where.
00:04:28Next up though, we have lexical scoping,
00:04:30so every nested element is creating its own scope,
00:04:32so we're able to declare a const label in three different div blocks here,
00:04:36and they don't collide.
00:04:37There's even one at the top of the function here that nothing is reading,
00:04:40and again, it is not conflicting.
00:04:41The same thing goes for every if, for, switch, or try statement.
00:04:44Each one has its own scopes,
00:04:46so the variables we declare, the functions we run,
00:04:48and the values we derive, they don't leak into the other scopes.
00:04:51This is another one of those features that's focused on co-locating our code,
00:04:54and again, it makes our components read in a top-to-bottom, linear way.
00:04:57Switching things up now from JavaScript, let's talk about styling.
00:05:00In TSRX, we actually have scoped styles,
00:05:02so you can just place a style block in your component,
00:05:04and the CSS that we write in there is scoped only to that component,
00:05:08with a unique hash being attached to the class name when it's compiled.
00:05:11So this card component has a card class,
00:05:13and notice here, it's also trying to use that card class,
00:05:16but it gets none of the card styling,
00:05:17because it has no style block of its own.
00:05:19It doesn't get the style from its parent,
00:05:21because it doesn't have that unique hash.
00:05:22If you do want to share styles across components though,
00:05:24TSRX has a style keyword,
00:05:26so the parent passes the style name in with this keyword
00:05:29to a component that accepts class name as a prop,
00:05:31and it will make sure that that unique hash that it generates goes along with it.
00:05:35So now notice has the same style as parent.
00:05:37You can also technically use a global selector around your styles
00:05:40to escape the scoping and apply those styles globally,
00:05:42but I think that's going to get a bit messy,
00:05:44and you'll lose track of where your styles are coming from.
00:05:46Personally, I'm a tailwind guy through and through,
00:05:48so I probably won't use this feature much,
00:05:50and I'll stick to tailwind,
00:05:51but it's pretty cool nonetheless.
00:05:53Next up, a feature for those of you that have been paying attention.
00:05:56In the code blocks that I've showed,
00:05:57there's been a small difference in the way that text is handled in these statements.
00:06:01Bare text inside of an element has to be double-quoted.
00:06:04We can't just write it in like we can in JSX.
00:06:07You can still use dynamic values though,
00:06:08and in a line like this one,
00:06:10which is in between two double-quoted strings,
00:06:12and TSRX will just simply concatenate this into one string when it compiles.
00:06:16Another option that you have is to simply stick to using a template literal.
00:06:19It gets the same result.
00:06:20For me, this has been one of the paper cuts of using TSRX
00:06:23because I just have so much muscle memory of not using quotes for text.
00:06:26Another text-based feature though,
00:06:27is that TSRX can actually handle strings that contain actual HTML markup,
00:06:31and you have two ways to render this.
00:06:33The first one is by simply using the text keyword,
00:06:35which is going to render in the escaped text,
00:06:38so you can see the literal HTML string,
00:06:40and it's also safe from cross-site scripting.
00:06:42So this is useful when you want to guarantee that something is going to be a string,
00:06:45and the source of that string is a little bit ambiguous,
00:06:48so you don't necessarily know its type when you're writing this code.
00:06:51The second option is for if you want to render the string as HTML,
00:06:54we can simply use the HTML keyword,
00:06:56and this parses it as real HTML,
00:06:58but this feature only works in Ripple with Vue supporting a narrower subset of it.
00:07:02Another feature not related to React,
00:07:03but it might be interesting to those of you that are using Ripple,
00:07:06Vue or Solid is lazy destructuring.
00:07:08If you destruct your props normally in these frameworks,
00:07:10you snapshot each value at call time,
00:07:12and that breaks the per-access reactivity.
00:07:14So in TSRX you can simply add an ampersand before the props,
00:07:18and while it looks like destructuring,
00:07:20each binding is actually compiled back to a property lookup where it's used.
00:07:23So the runtime sees each access individually,
00:07:25so signal updates still trigger re-renders,
00:07:28so it means that you get to keep the destructuring ergonomics,
00:07:30and the framework keeps its reactivity.
00:07:32The final feature I'll show is a nice and simple quality of life one.
00:07:35Have you ever had a prop where the value that you pass to the prop has the same name as that prop,
00:07:40most commonly in something like an on-change function?
00:07:42Well, with TSRX you can actually just write this as shorthand,
00:07:45similar to how we can with JavaScript objects.
00:07:47It's clean and simple.
00:07:49So overall, TSRX feels like it's attempting to blend normal JavaScript flow back into JSX
00:07:53and also add in a few quality of life improvements,
00:07:55and I like quite a lot of its elements.
00:07:57I genuinely think my main downfall with it is that it's too niche and too late
00:08:01when we have AI writing most of our code,
00:08:03and the code that AI is good at writing seems to be JSX and React.
00:08:07With that being said though, I did throw some demos at Claude using TSRX,
00:08:10and it did manage to write it well just based on the site's LLM.txt,
00:08:14but I still think I'm going to stick to normal React myself.
00:08:17The other downside is it feels like, especially for React,
00:08:19this is adding on more compiler magic on top,
00:08:21and it's also breaking flows that I've spent years learning,
00:08:24so it's personally not for me, but that does not mean it's bad.
00:08:27I think people coming from Svelte might like this a lot,
00:08:30and if you've used Ripple already, you probably already love this.
00:08:33So let me know in the comments down below if you do,
00:08:35while you're there subscribe, and as always, see you in the next one.
00:08:40[Music]
Community Posts
No posts yet. Be the first to write about this video!
Write about this video