I've tried to convert the Transcrypt react example to use a class component. Full code at the end but the main change is to convert this function component:
def ListItems(props):
items = props['items']
return [el('li', {'key': item}, item) for item in items]
to a class component:
class ListItems(React.Component):
def render(self):
items = self.props['items']
return [el('li', {'key': item}, item) for item in items]
But this fails with this stack trace in the browser:
Uncaught TypeError: Cannot read properties of undefined (reading '__new__')
at __class__ (app.12cad815.js:447:15)
at Object.parcelRequire.__target__/app.js../org.transcrypt.__runtime__.js (app.12cad815.js:31357:57)
at newRequire (app.12cad815.js:47:24)
at localRequire (app.12cad815.js:53:14)
at Object.parcelRequire.app.py../__target__/app.js (app.12cad815.js:31422:12)
at newRequire (app.12cad815.js:47:24)
at app.12cad815.js:81:7
at app.12cad815.js:120:3
Full code is based on the tutorial here: https://transcrypt.org/pdfs/rtptutorial.pdf
pyreact.py:
# __pragma__('skip')
def require(lib):
return lib
class document:
getElementById = None
addEventListener = None
# __pragma__ ('noskip')
React = require('react')
ReactDOM = require('react-dom')
createElement = React.createElement
useState = React.useState
def render(root_component, props, container):
def main():
ReactDOM.render(
createElement(root_component, props),
document.getElementById(container)
)
document.addEventListener('DOMContentLoaded', main)
app.py
from .pyreact import useState, render, createElement, React
el = createElement
class ListItems(React.Component):
def render(self):
items = self.props['items']
return [el('li', {'key': item}, item) for item in items]
def App():
newItem, setNewItem = useState("")
items, setItems = useState([])
def handleSubmit(event):
event.preventDefault()
setItems(items + [newItem]) # __:opov
setNewItem("")
def handleChange(event):
target = event["target"]
setNewItem(target["value"])
return el(
"form", {"onSubmit": handleSubmit},
el("label", {"htmlFor": "newItem"}, "New Item: "),
el("input", {"id": "newItem", "onChange": handleChange, "value": newItem}),
el("input", {"type": "submit"}),
el("ol", None,
el(ListItems, {"items": items})
)
)
render(App, None, 'root')
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="app.py"></script>
<title>React to Python</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Eventually I found tictacreact which gives a decent example of how to do this. Basically, add this to pyreact.py:
Then derive your component classes from
pyreact.Component
instead ofReact.Component
. To make the IDE happy, you could also add:to the skipped section of pyreact.py.