Proposal) Directives helper for redwood?

How do people here feel about having directives in redwoodjs?

Personally I would love to have them, I have never been fan of doing ternary operator in react for doing stuff like conditional rendering. Directives is a nice abstraction layer for doing most common task like iterating over list or showing something based on the state.

Alpine.js is wonderful example achieving interactivity solely on directives. Here have look GitHub - alpinejs/alpine: A rugged, minimal framework for composing JavaScript behavior in your markup.

Redwoodjs should ship with some directives helpers for more declarative ui. Why?

  • It’s easier for eyes to scan the code
  • Less code to write which it more elegant
  • Directives are more fun to use!

Another benefit I can see here is when there is an official redwood vscode extension in the future. We could provide snippets.

Secondly would be all developers coming out from angular, vue and svelte would appreciate having something like this. They will have much easier time to transition to react development!

I want to emphasis on “less code to write” maybe in the future there will be redwood styleguide like how to write idiomatic code in redwood fashion and I honestly believe helpers will play a bigger role.

Here is an example with jsx

Here is the same code with redwood directives helper

Here is a good video explaining the Power of the Directives!

Other common helpers could be
rw-if
rw-else
rw-elseif
rw-class
rw-show
rw-model Maybe for inputs

For reference checkout GitHub - peakchen90/babel-plugin-react-directives: A babel plugin that provides some directives for react(JSX), similar to directives of vue.

@peterp @thedavid @mojombo @rob What do you guys think?

2 Likes

I wish I could edit my original post but for some weird reason I don’t longer see the edit button? I write here instead

Redwoodjs shouldn’t be like example A above and more like example B.

For example,

Example A ) Yes we can do it!

Example B ) I know that you can do it but how can we do it better?

It’s all about improving the experience at the end of the day!

IMHO, directives make the surface API more complex by adding another layer of indirection. It’s also another concept to learn to be proficient with redwood.

For instance, here’s how to define new directives in Vue.js: https://vuejs.org/v2/guide/custom-directive.html. It needs its own DSL with concepts such as binding, events, hooks, etc.

Instead, to express the views, I’d much rather use standard javascript constructs that people are already familiar with and use the full power of the language. For instance, in your code sample above, we could use an <Ingredient> or <CustomUL>.

@phzbox I guess we need to move on to more “specific” examples,

Here is basic conditinal rendering example with jsx without directives

and here is with directives

@phzbox Be honest with me, which one is easier to spot what it’s going return?

When you are writing code you are writing for other people to understand so code clarity is really important.

@phzbox I highly recommend for you to watch this https://twitter.com/tobi/status/1182719837832916993?lang=ga
Tobi Lutke does an excellent job explaining what writing code is really about?

I wanted to voice my opinion on directives, but I’ll let the core redwood team decide on this as I feel this is more “opinion” territory. I’m fine either way and will support their decision.

But to answer your question, I honestly prefer the first approach at it’s standard javascript. There’s no hidden fee or magical feature and I know 100% what’s happening with this code. It can also be rewritten like this:

const Text = () => {
  ...

  const messages = yellAtPerson ? <h1>AAAHH</h1> : <span>hi, there!</span>
  return <>{message}</>
}

Looking at the second snippet, this isn’t “just javascript/react code” anymore. There’s now an additional layer that needs to be understood and debugged, especially if rw-if was a “custom-made directive” rather than a built-in one.

(By the way, this isn’t important as I get your point, but I think these snippets are a bit different. Isn’t the first one showing one or the other message, while the second one always showing “Hi, there” and only optionally showing “AAHHH”?)

2 Likes

(By the way, this isn’t important as I get your point, but I think these snippets are a bit different. Isn’t the first one showing one or the other message, while the second one always showing “Hi, there” and only optionally showing “AAHHH”?)

The only difference is that one had <h1> and the other is a <p> instead. Plus a <div> wrapped around it but don’t worry it’s just a pseudo code to get my point across. So both examples are going to show the second argument hi, there! because of the state, is false to begin with.

Listen mate sometimes you have to think outside the box and being open-minded. I mean when jsx first came out a lot people didn’t like either, and also like the rewrite you are referring to. I hate to break this to you but it was not much of rewrite either. It was putting stuff in a single line instead of multi lines.
This is the line that keeps my brain processing too,
yellAtPerson ? <h1>AAAHH</h1> : <span>hi, there!</span>

Something nice about having rw-if

<h1 rw-if={yellAtPerson}>AAAHH</h1> 
<span>hi, there!</span>

But the argument is always
“I’d rather do it in just JavaScript.” You know?”

Another solution would be using reusable components pattern like,

 <rw-If condition={user.role === 'admin'}>
   <Then>
      <h1>You can delete users </h1>
   </Then>
  </rw-If>

<span>hi, there!</span>

https://morello.dev/conditional-rendering-in-react

This only for if but I would still need stuff like,
<rw-For />
<rw-Else />
<rw-Elseif />
<rw-Class />
<rw-Show />

This is more markup based - with as little javascript as possible

<rw-For element={item} of-List={items} rw-Key={item.id}> 
  <h1>{item}<h1>
<rw-For/>

Or shorthand syntax,

<rw-For el={item} list={items} rw-Key={item.id}> 
  <h1>{item}<h1>
<rw-For/>

Maybe we can omit rw-Key={} all together and assume that it’s same as the el={element.id} based on convention?