我使用React和hypernova (带有php bindings)来执行一些React组件的服务器端渲染。下面是我的以下测试组件和来自超新星的响应。
Test.js
import React from 'react';
import { renderReact } from 'hypernova-react';
class Test extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<p onClick={() => alert('hey')}>click me</p>
);
}
}
export default renderReact('Test', Test);超新星响应
WF\Hypernova\JobResult Object
(
[error] =>
[html] =>
<div data-hypernova-key="Test" data-hypernova-id="e5af0b95-2a31-4ce4-8e36-808605fd4115">
<p data-reactroot="">click me</p>
</div>
<script type="application/json" data-hypernova-key="Test" data-hypernova-id="e5af0b95-2a31-4ce4-8e36-808605fd4115">
<!--{"prop1":"a","prop2":"b"}-->
</script>
[success] => 1
...
)如上所示,props正在成功传递,但是到处都找不到onClick处理程序。然而,它确实存在于转译后的代码中。
bundle.js
// code before and after class omitted for brevity
var Test = function (_React$Component) {
_inherits(Test, _React$Component);
function Test(props) {
_classCallCheck(this, Test);
return _possibleConstructorReturn(this, (Test.__proto__ || Object.getPrototypeOf(Test)).call(this, props));
}
_createClass(Test, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'p',
{ onClick: function onClick() {
return alert('hey');
} },
'click me'
);
}
}]);
return Test;
}(_react2.default.Component);
exports.default = (0, _hypernovaReact.renderReact)('Test', Test);在这个问题上,我唯一能找到的就是在github issue tracker中有人抱怨同样的事情,但显然<p>标签上不应该有事件处理程序;它应该存在于React提供的代码中。我还尝试使用带/不带箭头符号的类属性(在后一种情况下,在构造函数中显式绑定)来分配一个click处理程序。我已经在捆绑的React代码中添加了一个<script>标记,但这似乎没有什么不同。
这是一个bug,还是我做错了什么?
发布于 2018-06-08 23:06:02
事实证明,当使用服务器端呈现时,需要在服务器和客户端呈现组件。在我的例子中,这需要创建两个独立的webpack配置:一个用于hypernova服务器,另一个用于客户端React代码。然后,我需要添加如下代码
if (typeof document !== 'undefined') {
ReactDOM.render(<Test />, document.getElementById('puzzle'));
}在父组件中,这样React将在客户端呈现它们,而不会在服务器上生成异常。
这是我从this question那里发现的。
发布于 2020-02-12 02:58:29
是的,这还不足以使组件正常工作。
您在Test.js中做了什么
...
export default renderReact('Test', Test);它实际上是组件Test的服务器端呈现。所以正如你看到的那样,超新星正确地返回给你:
<div data-hypernova-key="Test" data-hypernova-id="e5af0b95-2a31-4ce4-8e36-808605fd4115">
<p data-reactroot="">click me</p>
</div>
<script type="application/json" data-hypernova-key="Test" data-hypernova-id="e5af0b95-2a31-4ce4-8e36-808605fd4115">
<!--{"prop1":"a","prop2":"b"}-->
</script>除了这一部分之外,您还需要加载客户端脚本并运行组件的再水化(https://reactjs.org/docs/react-dom.html#hydrate)。在超新星中,你需要准备另一个包含入口点的包:
// Test.js
const Test = () => {...}
export default Test
// index.js
import Test from './Test'
renderReact('Test', Test); // this will call hydrate when loaded in browser directly并在您的index.html页面上手动加载此包:
...
<script src='public/bundle.js'></script>为了帮助服务于此文件,hypernova具有以下配置:
hypernova({
...,
createApplication () {
const app = express()
app.get('/', (req, res) => res.status(200).json('OK'))
app.use('/public', express.static(path.join(process.cwd(), 'public')))
return app
}
})享受吧!希望它能帮助你弄清楚如何使用超新星。
https://stackoverflow.com/questions/50745760
复制相似问题