This is my 1st week into both React and coconut. Followed Juraj’s calculator workshop for coconut, and a very simple React like button tutorial you can find at https://reactjs.org/docs/add-react-to-a-website.html.
The React tutorial puts several <p>Some comment <div class="like_button_container"></div></p>
directly into an index.html
file, and then they have a LikeButton
class, and this code:
document.querySelectorAll('.like_button_container')
.forEach( domContainer => {
// Read the comments ID from a data-* attribute.
const commentID = parseInt( domContainer.dataset.commentid, 10 );
ReactDOM.render(
e(LikeButton, { commentID: commentID }),
domContainer
);
});
The React example’s index.html
is like:
<!doctype html>
<html lang="en">
<head></head>
<body>
<h1>hello world</h1>
<p>
Blabla Bla Jim, some little comment.
<div class="like_button_container" data-commentid="1"></div>
</p>
<p>
Blabla Bla Dwight, some little comment.
<div class="like_button_container" data-commentid="2"></div>
</p>
<p>
Blabla Bla Michael, some little comment.
<div class="like_button_container" data-commentid="3"></div>
</p>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="like_button.js"></script>
</body>
</html>
Now I tried to convert that to coconut.
But because of the workshop I followed and the Haxe API (js.Browser.querySelectorAll()
seems quite difficult to work with, with node types it seems hard to work with attributes) I chose the same approach as in the coconut workshop:
package;
import tink.state.*;
import tink.pure.*;
import coconut.Ui;
import coconut.ui.View;
class Main extends coconut.ui.View {
static function main() {
js.Browser.document
.querySelector('#please-to-render-here')
.appendChild(new Main({}).toElement()
);
}
function render() '
<div>
<p>
Blabla Bla Jim, some little comment.
<Like data_commentid="1" />
</p>
<p>
Blabla Bla Dwight, some little comment.
<Like data_commentid="2" />
</p>
<p>
Blabla Bla Michael, some little comment.
<Like data_commentid="3" />
</p>
</div>
';
And
class Like extends View {
@:attribute var data_commentid : String;
@:state var liked : Bool = false;
function render() '
<if {liked}>
<i>comment nr. {data_commentid} was liked by you</i>
<else>
<button onclick={liked = true}>Like</button>
</if>
';
}
It was surprisingly easy… But that’s not at all the same approach as in the React example I used.
This is more like no html, fully js-generated style.
Some questions to the coconut community:
- How to use the same approach as in the React example, i.e. iterate through some DOM nodes to update that content? do we have to use the
js.Browser
and so on? - Is it less advisable, e.g. in Coconut is the second approach more … used?
I’m trying to get a feel for the different possible approaches.