我已经尝试将Transcrypt-react示例转换为使用类组件。完整的代码在最后,但主要的变化是转换这个功能组件:
def ListItems(props):
items = props['items']
return [el('li', {'key': item}, item) for item in items]
到类组件:
class ListItems(React.Component):
def render(self):
items = self.props['items']
return [el('li', {'key': item}, item) for item in items]
但浏览器中的堆栈跟踪失败:
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
完整的代码基于这里的教程: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)
应用程序
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>
最终我找到了tictacreact,它提供了一个很好的例子来说明如何做到这一点。基本上,将此添加到pyreact.py:
registered_components = {}
class ComponentMeta(type):
def __new__(meta, name, bases, attribs):
cls = type.__new__(meta, name, bases, attribs)
registered_components[name] = cls
# override the default name='cls' property to make error messages and debugging more meaningful
descrip = Object.getOwnPropertyDescriptor(cls, 'name');
descrip.value = name
Object.defineProperty(cls, 'name', descrip);
return cls
class AbstractComponent(object, metaclass=ComponentMeta):
'''Superclass for React Components. Use Component below.'''
def __init__(self, props):
object.__init__(self)
def render(self):
return 'Subclass should override render()'
class Component(AbstractComponent, React.Component.prototype):
'''Superclass for React Components. PyReact version of React.Component'''
def __init__(self, props):
AbstractComponent.__init__(self)
React.Component.apply(self, [props])
然后从pyreact.Component
而不是React.Component
派生组件类。为了让IDE满意,您还可以添加:
class Object:
pass
到pyreact.py.的跳过部分