(No intention to spam, just questions popping up which I want to understand better. This thread is piling up nice answers so maybe I can redact it into a FAQ later on.)
How do I handle simple but oft-occurring cases with undefined involved?
In JS:
...
const { something } = useRouter()
if (!something) {
// not loaded yet
return </>
}
This is trivial to handle in JS. Since useRouter may return undefined, something will be destructured into undefined.
How do I do this in neatly ReScript? Right now, I have to use optionals and it becomes really messy.
Some good general advice is to bind only what you need, when you need it.
For JS function calls that introspect the number of arguments to determine what type a positional argument is, I would always reach for a new external binding to the same function as described in the docs here
If there’s only one last optional positional argument, you can also do something like this:
I love that you’re asking so many questions here, it’s going to help a lot of newcomers in the future. I’m sure it’s already been useful to some.
After using ReScript for a while, I’ve found this to be more useful than annoying. It prevents any kind of runtime issues with rendering undefined or something that isn’t valid jsx.
That said, it’s been very common in my codebase to do something like this:
I’m discovering that some names are common and the modules start shadowing each other. How do you deal with this? Almost any module I open, I get a type named t in my scope, which can surely cause confusion. open Promise seems like a sane thing to do, but I don’t want to import type tsilently.
Avoid opening modules at the top of the file where they can pollute the global scope of the module and confuse code readers. Try to open modules in smaller, local scopes. Only a few modules, like Belt, are explicitly designed to be opened globally, and even they can confuse people if they don’t read the documentation and understand the implications.
I think we need a style guide. Maybe it’s just me - I don’t know - but I have a much easier time getting into something after ready a style guide. It not only gives me a quick direction for laying out code, but also a sort of abstract overview of the language and the thinking that goes with it.
Especially considering how strict the autoformatter is, I think there should be a guide outlining naming conventions and such.
E.g., Namespace_Module for namespacing. Do we prefer #some_variant, #someVariant, #SomeVariant or #SOME_VARIANT - and why?
Yes, you could say “hey, this is up to you, who cares - do what you like in your projects,” but the same could be said of formatting entirely. For the sake of giving newbies even more ground to stand on, and maybe even more importantly, for us as a community to think about how we use the language, a style guide would be really helpful.
What are your pet peeves when it comes to abusing ReScript? What do you hate to see and why?
Yes, but the problem here is that I have to render the comopnent to do that. That means I can’t or shouldn’t do it outside a component render function, right?
As you know, Next uses filenames for routing. I think earlier in this thread, someone suggested I put .js-files to import the res-components. This was fine when I had 5-7 pages, but now that the project is 30-40 pages with 20 api points, the ReScript source folder is becoming crowded:
And so on, which are in turned imported from a bunch of js files.
I understand they define the interface. Why would I want to put it separately? It reminds me of .h and .c files. Is that a good way of thinking about .resi files/
What are some tips to become more productive with ReScript?
Do you have any major or minor workflow tips to increaes productivity? Right now, I’m spending a lot of time on bindings. A large part of an app is interacting with third party libs and APIs. If I don’t make them typesafe, type unsafety creeps into my entire app, so that is taking a lot of time.