The question is - how does the React component model (or its JSX representation) apply in this particular context - other than appealing to developers who are already familiar with it (for better or worse)?
My point isn’t to critique your contribution - thumbs up for sharing - but to encourage thinking (and perhaps develop a more compelling rationale for somebody to use this).
Interestingly I’ve never found a reaction by the React community to the conclusion of the Elm community that the component model does not work in a single source of truth architecture.
Richard Feldman came from React and reports on components not scaling well in Elm Europe 2017 - Scaling Elm Apps. He reports that the component approach introduced too much accidental complexity over an approach that managed the model, view, and update aspects separately. It roughly focuses on “narrowing types” on the inputs of the constituent functions that comprise the model update and view render in order to limit the complexity of each constituent function to make everything easier to reason about.
By contrast in React/Redux a component often has to rifle around in the whole application model to get the information it needs (and therefore is coupled to the model’s layout), pay attention to the props that are handed down by the parent component, possibly use some of the (function) props to affect the local (i.e. non-centralized) state of any of it’s ancestor components, or even receive child components (render props/component injection).
So I don’t really have to worry about that as much in Fireblast because I’m doing all the processing at compile time. So we have the same iolists as with regular Phoenix. Though they are split up more probably. I can do some benchmarking on it just to make sure I’m not doing anything dumb.
Fireblast is only the JSX part really at this stage. With integration into Phoenix Live it would become closer to React.
I’ll definitely look at the links you provided because we don’t want to repeat the same mistakes.
The good thing about announcing a project is that you feel guilty for things you haven’t done yet but think have to be done.
One of those things was a basic escaping of variable data passed into the component so people can’t just inject what ever into it. Now with the help of Phoenix.HTML I have a version out.
I do not quite get what you are saying there. Phoenix views have some magic behind to generate functions, but in general Your example can be written as:
Link.render(conn: conn)
Or any other function, as what you call “Phoenix templates” are just functions, exactly like React render functions, with only one main difference - as Elixir is compiled language these functions can be generated during compile-time from external text files. So while I see it as a nice learning project I do not really get what is the improvement there.
Of course you can use what ever module in the <%= %> and you can even use render(YourApp.UserView, "index.html", name: "John<br/>Doe") in there.
But it’s just about how easy it is to read the.
You can use ~E and ~e but they don’t accept #{}
So things like:
list = [1, 2, 3]
render_item = fn item ->
~x(<p>#{item}</p>)
end
~x(
<div id="1">
#{Enum.map(list, render_item)}
</div>
)
Is really hard to replicate just with sigils, you can use the EEx do get the same effect.
It just has to do with familiarity. Vuejs look really different from React but at some level they are doing the same things. But in our case we are actually getting the same result because we don’t have to contend with a javascript rendering part.
There are going to be case where I would have a clear win over Phoenix templates. That is with something like a Trans tag.
I’m not sure why one would need react inspired syntax to create a macro, which translates eex content into a call to gettext. It could just as well be a macro trans called like that:
<%= trans do %>
Hello <a href="/world">World</a>
<% end %>
That is a pretty good suggestion. I’ll probably implement something like that a long side my implementation of Trans so people that prefer templating also get something
Yeah that is what I said, that you can use EEx to get the same results. Sigils have the string interpolation which is pretty typical for trying to accomplish these sort of things.
EEx introduces really nice templating behaviors but like the difference between Vue.js vs React.js, things are close but feel really different for people that aren’t used to this kind of behaviour.
It’s actually a choice the Phoenix HTML takes not to use #{} there isn’t anything inherit that makes it not work. I think it’s fair they don’t want to have two different ways of doing the same thing.
I think that the reasoning was to avoid confusion about when would expanse happen. Somebody could assume that #{} will take place during compilation of the template, not during execution of one. But in the end the difference is small enough to not be an issue in my opinion.
(
arg0 = case({1, 1}) do
{:safe, data} ->
data
bin when is_binary(bin) ->
Plug.HTML.html_escape_to_iodata(bin)
other ->
Phoenix.HTML.Safe.to_iodata(other)
end
{:safe, ["<foo something=", arg0, "><bar2 something=\"a\"/><a>2</a></foo>"]}
)
But you can use @foo as well and then it will extract the requested values from variable named assigns. So you can do:
def my_func(assigns) do
~E[<foo something="<%= @foo %>">…</foo>]
end
my_func(foo: {1, 1})
And it will work as expected. Only “nice fancy thing” I see in your code is that (if I understand your example correctly) is that:
I might need to let some modules have access to the preprocessed children.
I’m also ensuring that the code makes some sense because I’m parsing the xml, so making sure you are closing you elements and stuff like that is ensured.
But the fundamental reason to create this library isn’t to be cooler or have more features than Phoenix. It’s about being able to port React code easily and make people with React experience more productive.
In that case I say great, and I cross fingers for your endeavour. It is very important to know what is you goal and what solutions are already available. From your words it seems that you are already know why your project exist and you do not “blindly implement it because of reasons”. Great!